<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Spring Data MongoDB - Preface | Docs4dev</title>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="Spring Data for MongoDB is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities.">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="true">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta property="og:type" content="website">
<meta property="og:title" content="Spring Data MongoDB - Preface">
<meta property="og:url" content="https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/">
<meta property="og:site_name" content="Docs4dev">
<meta property="og:locale" content="zh_CN">
<meta name="twitter:card" content="Spring Data for MongoDB is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities.">
<meta name="generator" content="Docs4dev template engine">
<link rel="stylesheet" href="static/css/app.min.css">
<link rel="shortcut icon" href="https://www.docs4dev.com/static/images/favicon.ico" type="image/x-icon">
<script async="" src="static/js/js.js"></script>
<script async="" src="static/js/adsbygoogle.js" crossorigin="anonymous"></script>
<script>
    window.dataLayer = window.dataLayer || [];

    function gtag() {
      dataLayer.push(arguments);
    }

    gtag('js', new Date());
    gtag('config', 'UA-129571937-1');
  </script>
<link rel="amphtml" href="https://www.docs4dev.com/amp/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/index.html">

<script type="application/ld+json">{"name":null,"headline":"Spring Data MongoDB-Preface","inLanguage":"en-US","version":"2.2.1.RELEASE","image":"/static/icon/icon-spring-data.png","datePublished":"2021-05-20T12:51:01Z","dateCreated":"2021-05-20T12:51:01Z","dateModified":"2021-07-03T12:24:36Z","@context":"https://schema.org/","@type":"APIReference","abstract":"Spring Data for MongoDB is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities."}</script>
</head>
<body>
<div class="book with-summary">
<div class="book-summary">
<div class="logo">
<a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference');" style="color: inherit;">
<img src="static/picture/icon-spring-data.png" style="width: 48px; height: 48px;" alt="Logo">
</a>
<b style="color: inherit; margin-left: 8px;">Spring Data MongoDB</b>
</div>
<div class="item">
<div>
<label for="version">版本</label>
<select id="version" onchange="onVersionChange(this)">
<option value="2.2.1.RELEASE" selected="selected">2.2.1.RELEASE</option>
</select>
</div>
<div style="margin-top: 8px;">
<label for="language">语言</label>
<select id="language" onchange="onLangChange(this)" value="en">
<option value="en" selected="selected">English</option>
<option value="zh">中文</option>
</select>
</div>

</div>
<div class="item menus">
<a title="Table of Contents" style="margin-right: 8px;" href="#">
<i class="fa fa-chevron-left"></i>
<span style="margin-left: 2px;">返回目录</span>
</a>
</div>
<nav role="navigation" id="navigation">
<ul class="summary">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#preface');" title="Preface"> Preface </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#get-started:first-steps:spring');" title="1. Learning Spring"> 1. Learning Spring </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#get-started:first-steps:nosql');" title="2. Learning NoSQL and Document databases"> 2. Learning NoSQL and Document databases </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#requirements');" title="3. Requirements"> 3. Requirements </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#get-started:help');" title="4. Additional Help Resources"> 4. Additional Help Resources </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#get-started:up-to-date');" title="5. Following Development"> 5. Following Development </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features');" title="6. New &amp; Noteworthy"> 6. New &amp; Noteworthy </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.2-2-0');" title="6.1. What’s New in Spring Data MongoDB 2.2"> 6.1. What’s New in Spring Data MongoDB 2.2 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.2-1-0');" title="6.2. What’s New in Spring Data MongoDB 2.1"> 6.2. What’s New in Spring Data MongoDB 2.1 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.2-0-0');" title="6.3. What’s New in Spring Data MongoDB 2.0"> 6.3. What’s New in Spring Data MongoDB 2.0 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.1-10-0');" title="6.4. What’s New in Spring Data MongoDB 1.10"> 6.4. What’s New in Spring Data MongoDB 1.10 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.1-9-0');" title="6.5. What’s New in Spring Data MongoDB 1.9"> 6.5. What’s New in Spring Data MongoDB 1.9 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.1-8-0');" title="6.6. What’s New in Spring Data MongoDB 1.8"> 6.6. What’s New in Spring Data MongoDB 1.8 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#new-features.1-7-0');" title="6.7. What’s New in Spring Data MongoDB 1.7"> 6.7. What’s New in Spring Data MongoDB 1.7 </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#dependencies');" title="7. Dependencies"> 7. Dependencies </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#dependencies.spring-boot');" title="7.1. Dependency Management with Spring Boot"> 7.1. Dependency Management with Spring Boot </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#dependencies.spring-framework');" title="7.2. Spring Framework"> 7.2. Spring Framework </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories');" title="8. Working with Spring Data Repositories"> 8. Working with Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.core-concepts');" title="8.1. Core concepts"> 8.1. Core concepts </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-methods');" title="8.2. Query methods"> 8.2. Query methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.definition');" title="8.3. Defining Repository Interfaces"> 8.3. Defining Repository Interfaces </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.definition-tuning');" title="8.3.1. Fine-tuning Repository Definition"> 8.3.1. Fine-tuning Repository Definition </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.multiple-modules');" title="8.3.2. Using Repositories with Multiple Spring Data Modules"> 8.3.2. Using Repositories with Multiple Spring Data Modules </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-methods.details');" title="8.4. Defining Query Methods"> 8.4. Defining Query Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-methods.query-lookup-strategies');" title="8.4.1. Query Lookup Strategies"> 8.4.1. Query Lookup Strategies </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-methods.query-creation');" title="8.4.2. Query Creation"> 8.4.2. Query Creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-methods.query-property-expressions');" title="8.4.3. Property Expressions"> 8.4.3. Property Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.special-parameters');" title="8.4.4. Special parameter handling"> 8.4.4. Special parameter handling </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.paging-and-sorting');" title="Paging and Sorting"> Paging and Sorting </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.limit-query-result');" title="8.4.5. Limiting Query Results"> 8.4.5. Limiting Query Results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.collections-and-iterables');" title="8.4.6. Repository Methods Returning Collections or Iterables"> 8.4.6. Repository Methods Returning Collections or Iterables </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.collections-and-iterables.streamable');" title="Using Streamable as Query Method Return Type"> Using Streamable as Query Method Return Type </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.collections-and-iterables.streamable-wrapper');" title="Returning Custom Streamable Wrapper Types"> Returning Custom Streamable Wrapper Types </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.collections-and-iterables.vavr');" title="Support for Vavr Collections"> Support for Vavr Collections </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.nullability');" title="8.4.7. Null Handling of Repository Methods"> 8.4.7. Null Handling of Repository Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.nullability.annotations');" title="Nullability Annotations"> Nullability Annotations </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.nullability.kotlin');" title="Nullability in Kotlin-based Repositories"> Nullability in Kotlin-based Repositories </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-streaming');" title="8.4.8. Streaming query results"> 8.4.8. Streaming query results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.query-async');" title="8.4.9. Async query results"> 8.4.9. Async query results </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.create-instances');" title="8.5. Creating Repository Instances"> 8.5. Creating Repository Instances </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.create-instances.spring');" title="8.5.1. XML configuration"> 8.5.1. XML configuration </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Using filters"> Using filters </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.create-instances.java-config');" title="8.5.2. JavaConfig"> 8.5.2. JavaConfig </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.create-instances.standalone');" title="8.5.3. Standalone usage"> 8.5.3. Standalone usage </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.custom-implementations');" title="8.6. Custom Implementations for Spring Data Repositories"> 8.6. Custom Implementations for Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.single-repository-behavior');" title="8.6.1. Customizing Individual Repositories"> 8.6.1. Customizing Individual Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Configuration"> Configuration </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.customize-base-repository');" title="8.6.2. Customize the Base Repository"> 8.6.2. Customize the Base Repository </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.domain-events');" title="8.7. Publishing Events from Aggregate Roots"> 8.7. Publishing Events from Aggregate Roots </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.extensions');" title="8.8. Spring Data Extensions"> 8.8. Spring Data Extensions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.extensions.querydsl');" title="8.8.1. Querydsl Extension"> 8.8.1. Querydsl Extension </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.web');" title="8.8.2. Web support"> 8.8.2. Web support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.web.basic');" title="Basic Web Support"> Basic Web Support </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.web.pageables');" title="Hypermedia Support for Pageables"> Hypermedia Support for Pageables </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.web.binding');" title="Web Databinding Support"> Web Databinding Support </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.web.type-safe');" title="Querydsl Web Support"> Querydsl Web Support </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#core.repository-populators');" title="8.8.3. Repository Populators"> 8.8.3. Repository Populators </a> </li>
</ul> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#reference');" title="Reference Documentation"> Reference Documentation </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#introduction');" title="9. Introduction"> 9. Introduction </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="9.1. Document Structure"> 9.1. Document Structure </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.core');" title="10. MongoDB support"> 10. MongoDB support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-getting-started');" title="10.1. Getting Started"> 10.1. Getting Started </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.examples-repo');" title="10.2. Examples Repository"> 10.2. Examples Repository </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-connectors');" title="10.3. Connecting to MongoDB with Spring"> 10.3. Connecting to MongoDB with Spring </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-java-config');" title="10.3.1. Registering a Mongo Instance by using Java-based Metadata"> 10.3.1. Registering a Mongo Instance by using Java-based Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-xml-config');" title="10.3.2. Registering a Mongo Instance by Using XML-based Metadata"> 10.3.2. Registering a Mongo Instance by Using XML-based Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-db-factory');" title="10.3.3. The MongoDbFactory Interface"> 10.3.3. The MongoDbFactory Interface </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-db-factory-java');" title="10.3.4. Registering a MongoDbFactory Instance by Using Java-based Metadata"> 10.3.4. Registering a MongoDbFactory Instance by Using Java-based Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-db-factory-xml');" title="10.3.5. Registering a MongoDbFactory Instance by Using XML-based Metadata"> 10.3.5. Registering a MongoDbFactory Instance by Using XML-based Metadata </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template');" title="10.4. Introduction to MongoTemplate"> 10.4. Introduction to MongoTemplate </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.instantiating');" title="10.4.1. Instantiating MongoTemplate"> 10.4.1. Instantiating MongoTemplate </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.writeresultchecking');" title="10.4.2. WriteResultChecking Policy"> 10.4.2. WriteResultChecking Policy </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.writeconcern');" title="10.4.3. WriteConcern"> 10.4.3. WriteConcern </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.writeconcernresolver');" title="10.4.4. WriteConcernResolver"> 10.4.4. WriteConcernResolver </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.save-update-remove');" title="10.5. Saving, Updating, and Removing Documents"> 10.5. Saving, Updating, and Removing Documents </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.id-handling');" title="10.5.1. How the _id Field is Handled in the Mapping Layer"> 10.5.1. How the _id Field is Handled in the Mapping Layer </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.type-mapping');" title="10.5.2. Type Mapping"> 10.5.2. Type Mapping </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Customizing Type Mapping"> Customizing Type Mapping </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Configuring Custom Type Mapping"> Configuring Custom Type Mapping </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.save-insert');" title="10.5.3. Methods for Saving and Inserting Documents"> 10.5.3. Methods for Saving and Inserting Documents </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.save-insert.collection');" title="Into Which Collection Are My Documents Saved?"> Into Which Collection Are My Documents Saved? </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.save-insert.individual');" title="Inserting or Saving Individual Objects"> Inserting or Saving Individual Objects </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.save-insert.batch');" title="Inserting Several Objects in a Batch"> Inserting Several Objects in a Batch </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-update');" title="10.5.4. Updating Documents in a Collection"> 10.5.4. Updating Documents in a Collection </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-update.methods');" title="Methods for Executing Updates for Documents"> Methods for Executing Updates for Documents </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-update.update');" title="Methods in the Update Class"> Methods in the Update Class </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.upserts');" title="10.5.5. “Upserting” Documents in a Collection"> 10.5.5. “Upserting” Documents in a Collection </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.find-and-upsert');" title="10.5.6. Finding and Upserting Documents in a Collection"> 10.5.6. Finding and Upserting Documents in a Collection </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.find-and-replace');" title="10.5.7. Finding and Replacing Documents"> 10.5.7. Finding and Replacing Documents </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.delete');" title="10.5.8. Methods for Removing Documents"> 10.5.8. Methods for Removing Documents </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.optimistic-locking');" title="10.5.9. Optimistic Locking"> 10.5.9. Optimistic Locking </a> </li>
 </ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.query');" title="10.6. Querying Documents"> 10.6. Querying Documents </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-query');" title="10.6.1. Querying Documents in a Collection"> 10.6.1. Querying Documents in a Collection </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-query.criteria');" title="Methods for the Criteria Class"> Methods for the Criteria Class </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-template-query.query');" title="Methods for the Query class"> Methods for the Query class </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.querying');" title="10.6.2. Methods for Querying for Documents"> 10.6.2. Methods for Querying for Documents </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.query.distinct');" title="10.6.3. Query Distinct Values"> 10.6.3. Query Distinct Values </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.geospatial');" title="10.6.4. GeoSpatial Queries"> 10.6.4. GeoSpatial Queries </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.geo-near');" title="Geo-near Queries"> Geo-near Queries </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.geo-json');" title="10.6.5. GeoJSON Support"> 10.6.5. GeoJSON Support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="GeoJSON Types in Domain Classes"> GeoJSON Types in Domain Classes </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="GeoJSON Types in Repository Query Methods"> GeoJSON Types in Repository Query Methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Metrics and Distance calculation"> Metrics and Distance calculation </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.textsearch');" title="10.6.6. Full-text Queries"> 10.6.6. Full-text Queries </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Full-text Search"> Full-text Search </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.collation');" title="10.6.7. Collations"> 10.6.7. Collations </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.jsonSchema');" title="JSON Schema"> JSON Schema </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.jsonSchema');" title="10.6.8. JSON Schema"> 10.6.8. JSON Schema </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.query.fluent-template-api');" title="10.6.9. Fluent Template API"> 10.6.9. Fluent Template API </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.query.kotlin-support');" title="10.6.10. Type-safe Queries for Kotlin"> 10.6.10. Type-safe Queries for Kotlin </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.query.additional-query-options');" title="10.6.11. Additional Query Options"> 10.6.11. Additional Query Options </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example');" title="10.7. Query by Example"> 10.7. Query by Example </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example.introduction');" title="10.7.1. Introduction"> 10.7.1. Introduction </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example.usage');" title="10.7.2. Usage"> 10.7.2. Usage </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example.matchers');" title="10.7.3. Example Matchers"> 10.7.3. Example Matchers </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example.execution');" title="10.7.4. Running an Example"> 10.7.4. Running an Example </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#query-by-example.untyped');" title="10.7.5. Untyped Example"> 10.7.5. Untyped Example </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mapreduce');" title="10.8. Map-Reduce Operations"> 10.8. Map-Reduce Operations </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mapreduce.example');" title="10.8.1. Example Usage"> 10.8.1. Example Usage </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.server-side-scripts');" title="10.9. Script Operations"> 10.9. Script Operations </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.group');" title="10.10. Group Operations"> 10.10. Group Operations </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.group.example');" title="10.10.1. Example Usage"> 10.10.1. Example Usage </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation');" title="10.11. Aggregation Framework Support"> 10.11. Aggregation Framework Support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.basic-concepts');" title="10.11.1. Basic Concepts"> 10.11.1. Basic Concepts </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.supported-aggregation-operations');" title="10.11.2. Supported Aggregation Operations"> 10.11.2. Supported Aggregation Operations </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.projection');" title="10.11.3. Projection Expressions"> 10.11.3. Projection Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.facet');" title="10.11.4. Faceted Classification"> 10.11.4. Faceted Classification </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Buckets"> Buckets </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Multi-faceted Aggregation"> Multi-faceted Aggregation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.sort-by-count');" title="Sort By Count"> Sort By Count </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.projection.expressions');" title="Spring Expression Support in Projection Expressions"> Spring Expression Support in Projection Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.aggregation.examples');" title="Aggregation Framework Examples"> Aggregation Framework Examples </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.custom-converters');" title="10.11.5. Custom Conversions - Overriding Default Mapping"> 10.11.5. Custom Conversions - Overriding Default Mapping </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.custom-converters.writer');" title="Saving by Using a Registered Spring Converter"> Saving by Using a Registered Spring Converter </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.custom-converters.reader');" title="Reading by Using a Spring Converter"> Reading by Using a Spring Converter </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.custom-converters.xml');" title="Registering Spring Converters with the MongoConverter"> Registering Spring Converters with the MongoConverter </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.converter-disambiguation');" title="Converter Disambiguation"> Converter Disambiguation </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.index-and-collections');" title="10.12. Index and Collection Management"> 10.12. Index and Collection Management </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.index-and-collections.index');" title="10.12.1. Methods for Creating an Index"> 10.12.1. Methods for Creating an Index </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.index-and-collections.access');" title="10.12.2. Accessing Index Information"> 10.12.2. Accessing Index Information </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.index-and-collections.collection');" title="10.12.3. Methods for Working with a Collection"> 10.12.3. Methods for Working with a Collection </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.commands');" title="10.13. Executing Commands"> 10.13. Executing Commands </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-template.commands.execution');" title="10.13.1. Methods for executing commands"> 10.13.1. Methods for executing commands </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.mapping-usage.events');" title="10.14. Lifecycle Events"> 10.14. Lifecycle Events </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#entity-callbacks');" title="10.15. Entity Callbacks"> 10.15. Entity Callbacks </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#entity-callbacks.implement');" title="10.15.1. Implementing Entity Callbacks"> 10.15.1. Implementing Entity Callbacks </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#entity-callbacks.register');" title="10.15.2. Registering Entity Callbacks"> 10.15.2. Registering Entity Callbacks </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.entity-callbacks');" title="10.15.3. Store specific EntityCallbacks"> 10.15.3. Store specific EntityCallbacks </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.exception');" title="10.16. Exception Translation"> 10.16. Exception Translation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.executioncallback');" title="10.17. Execution Callbacks"> 10.17. Execution Callbacks </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#gridfs');" title="10.18. GridFS Support"> 10.18. GridFS Support </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#tailable-cursors');" title="10.19. Infinite Streams with Tailable Cursors"> 10.19. Infinite Streams with Tailable Cursors </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#tailable-cursors.sync');" title="10.19.1. Tailable Cursors with MessageListener"> 10.19.1. Tailable Cursors with MessageListener </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#tailable-cursors.reactive');" title="10.19.2. Reactive Tailable Cursors"> 10.19.2. Reactive Tailable Cursors </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#change-streams');" title="10.20. Change Streams"> 10.20. Change Streams </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="10.20.1. Change Streams with MessageListener"> 10.20.1. Change Streams with MessageListener </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="10.20.2. Reactive Change Streams"> 10.20.2. Reactive Change Streams </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="10.20.3. Resuming Change Streams"> 10.20.3. Resuming Change Streams </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.sessions');" title="11. MongoDB Sessions"> 11. MongoDB Sessions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.sessions.sync');" title="11.1. Synchronous ClientSession support."> 11.1. Synchronous ClientSession support. </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.sessions.reactive');" title="11.2. Reactive ClientSession support"> 11.2. Reactive ClientSession support </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions');" title="12. MongoDB Transactions"> 12. MongoDB Transactions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.transaction-template');" title="12.1. Transactions with TransactionTemplate"> 12.1. Transactions with TransactionTemplate </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.tx-manager');" title="12.2. Transactions with MongoTransactionManager"> 12.2. Transactions with MongoTransactionManager </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.reactive');" title="12.3. Reactive Transactions"> 12.3. Reactive Transactions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.reactive-operator');" title="12.4. Transactions with TransactionalOperator"> 12.4. Transactions with TransactionalOperator </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.reactive-tx-manager');" title="12.5. Transactions with ReactiveMongoTransactionManager"> 12.5. Transactions with ReactiveMongoTransactionManager </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.transactions.behavior');" title="12.6. Special behavior inside transactions"> 12.6. Special behavior inside transactions </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive');" title="13. Reactive MongoDB support"> 13. Reactive MongoDB support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb-reactive-getting-started');" title="13.1. Getting Started"> 13.1. Getting Started </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.driver');" title="13.2. Connecting to MongoDB with Spring and the Reactive Streams Driver"> 13.2. Connecting to MongoDB with Spring and the Reactive Streams Driver </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.mongo-java-config');" title="13.2.1. Registering a MongoClient Instance Using Java-based Metadata"> 13.2.1. Registering a MongoClient Instance Using Java-based Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.mongo-db-factory');" title="13.2.2. The ReactiveMongoDatabaseFactory Interface"> 13.2.2. The ReactiveMongoDatabaseFactory Interface </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.mongo-db-factory-java');" title="13.2.3. Registering a ReactiveMongoDatabaseFactory Instance by Using Java-based Metadata"> 13.2.3. Registering a ReactiveMongoDatabaseFactory Instance by Using Java-based Metadata </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template');" title="13.3. Introduction to ReactiveMongoTemplate"> 13.3. Introduction to ReactiveMongoTemplate </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template.instantiating');" title="13.3.1. Instantiating ReactiveMongoTemplate"> 13.3.1. Instantiating ReactiveMongoTemplate </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template.writeresultchecking');" title="13.3.2. WriteResultChecking Policy"> 13.3.2. WriteResultChecking Policy </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template.writeconcern');" title="13.3.3. WriteConcern"> 13.3.3. WriteConcern </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template.writeconcernresolver');" title="13.3.4. WriteConcernResolver"> 13.3.4. WriteConcernResolver </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.template.save-update-remove');" title="13.4. Saving, Updating, and Removing Documents"> 13.4. Saving, Updating, and Removing Documents </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.executioncallback');" title="13.5. Execution Callbacks"> 13.5. Execution Callbacks </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#reactive.gridfs');" title="13.6. GridFS Support"> 13.6. GridFS Support </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.repositories');" title="14. MongoDB Repositories"> 14. MongoDB Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-repo-intro');" title="14.1. Introduction"> 14.1. Introduction </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo-repo-usage');" title="14.2. Usage"> 14.2. Usage </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries');" title="14.3. Query Methods"> 14.3. Query Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.delete');" title="14.3.1. Repository Delete Queries"> 14.3.1. Repository Delete Queries </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.geo-spatial');" title="14.3.2. Geo-spatial Repository Queries"> 14.3.2. Geo-spatial Repository Queries </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Geo-near Queries"> Geo-near Queries </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.json-based');" title="14.3.3. MongoDB JSON-based Query Methods and Field Restriction"> 14.3.3. MongoDB JSON-based Query Methods and Field Restriction </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.sort');" title="14.3.4. Sorting Query Method results"> 14.3.4. Sorting Query Method results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.json-spel');" title="14.3.5. JSON-based Queries with SpEL Expressions"> 14.3.5. JSON-based Queries with SpEL Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.type-safe');" title="14.3.6. Type-safe Query Methods"> 14.3.6. Type-safe Query Methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.full-text');" title="14.3.7. Full-text Search Queries"> 14.3.7. Full-text Search Queries </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#projections');" title="14.3.8. Projections"> 14.3.8. Projections </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#projections.interfaces');" title="Interface-based Projections"> Interface-based Projections </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#projections.dtos');" title="Class-based Projections (DTOs)"> Class-based Projections (DTOs) </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#projection.dynamic');" title="Dynamic Projections"> Dynamic Projections </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.queries.aggregation');" title="14.3.9. Aggregation Repository Methods"> 14.3.9. Aggregation Repository Methods </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.repositories.misc.cdi-integration');" title="14.4. CDI Integration"> 14.4. CDI Integration </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.repositories');" title="15. Reactive MongoDB repositories"> 15. Reactive MongoDB repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.repositories.libraries');" title="15.1. Reactive Composition Libraries"> 15.1. Reactive Composition Libraries </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.repositories.usage');" title="15.2. Usage"> 15.2. Usage </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.reactive.repositories.features');" title="15.3. Features"> 15.3. Features </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.reactive.repositories.queries.geo-spatial');" title="15.3.1. Geo-spatial Repository Queries"> 15.3.1. Geo-spatial Repository Queries </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Geo-near Queries"> Geo-near Queries </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb.reactive.repositories.queries.type-safe');" title="15.3.2. Type-safe Query Methods"> 15.3.2. Type-safe Query Methods </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#auditing');" title="16. Auditing"> 16. Auditing </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#auditing.basics');" title="16.1. Basics"> 16.1. Basics </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#auditing.annotations');" title="16.1.1. Annotation-based Auditing Metadata"> 16.1.1. Annotation-based Auditing Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#auditing.interfaces');" title="16.1.2. Interface-based Auditing Metadata"> 16.1.2. Interface-based Auditing Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#auditing.auditor-aware');" title="16.1.3. AuditorAware"> 16.1.3. AuditorAware </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.auditing');" title="16.2. General Auditing Configuration for MongoDB"> 16.2. General Auditing Configuration for MongoDB </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-chapter');" title="17. Mapping"> 17. Mapping </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping.fundamentals');" title="17.1. Object Mapping Fundamentals"> 17.1. Object Mapping Fundamentals </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping.object-creation');" title="17.1.1. Object creation"> 17.1.1. Object creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping.property-population');" title="17.1.2. Property population"> 17.1.2. Property population </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="17.1.3. General recommendations"> 17.1.3. General recommendations </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping.kotlin');" title="17.1.4. Kotlin support"> 17.1.4. Kotlin support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Kotlin object creation"> Kotlin object creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Property population of Kotlin data classes"> Property population of Kotlin data classes </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-conventions');" title="17.2. Convention-based Mapping"> 17.2. Convention-based Mapping </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping.conventions.id-field');" title="17.2.1. How the _id field is handled in the mapping layer."> 17.2.1. How the _id field is handled in the mapping layer. </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-conversion');" title="17.3. Data Mapping and Type Conversion"> 17.3. Data Mapping and Type Conversion </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-configuration');" title="17.4. Mapping Configuration"> 17.4. Mapping Configuration </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage');" title="17.5. Metadata-based Mapping"> 17.5. Metadata-based Mapping </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-annotations');" title="17.5.1. Mapping Annotation Overview"> 17.5.1. Mapping Annotation Overview </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-custom-object-construction');" title="17.5.2. Customized Object Construction"> 17.5.2. Customized Object Construction </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-indexes.compound-index');" title="17.5.3. Compound Indexes"> 17.5.3. Compound Indexes </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-indexes.hashed-index');" title="17.5.4. Hashed Indexes"> 17.5.4. Hashed Indexes </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-indexes.text-index');" title="17.5.5. Text Indexes"> 17.5.5. Text Indexes </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-references');" title="17.5.6. Using DBRefs"> 17.5.6. Using DBRefs </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-usage-events');" title="17.5.7. Mapping Framework Events"> 17.5.7. Mapping Framework Events </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mapping-explicit-converters');" title="17.5.8. Overriding Mapping with Explicit Converters"> 17.5.8. Overriding Mapping with Explicit Converters </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin');" title="18. Kotlin Support"> 18. Kotlin Support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.requirements');" title="18.1. Requirements"> 18.1. Requirements </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.null-safety');" title="18.2. Null Safety"> 18.2. Null Safety </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.mapping');" title="18.3. Object Mapping"> 18.3. Object Mapping </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.extensions');" title="18.4. Extensions"> 18.4. Extensions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.coroutines');" title="18.5. Coroutines"> 18.5. Coroutines </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.coroutines.dependencies');" title="18.5.1. Dependencies"> 18.5.1. Dependencies </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#kotlin.coroutines.reactive');" title="18.5.2. How Reactive translates to Coroutines?"> 18.5.2. How Reactive translates to Coroutines? </a> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.cross.store');" title="19. Cross Store Support"> 19. Cross Store Support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb_cross-store-configuration');" title="19.1. Cross Store Configuration"> 19.1. Cross Store Configuration </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb_cross-store-application');" title="19.2. Writing the Cross Store Application"> 19.2. Writing the Cross Store Application </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.jmx');" title="20. JMX support"> 20. JMX support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongodb:jmx-configuration');" title="20.1. MongoDB JMX Configuration"> 20.1. MongoDB JMX Configuration </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3');" title="21. MongoDB 3.0 Support"> 21. MongoDB 3.0 Support </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="21.1. Using Spring Data MongoDB with MongoDB 3.0"> 21.1. Using Spring Data MongoDB with MongoDB 3.0 </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.configuration');" title="21.1.1. Configuration Options"> 21.1.1. Configuration Options </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.write-concern');" title="21.1.2. WriteConcern and WriteConcernChecking"> 21.1.2. WriteConcern and WriteConcernChecking </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.authentication');" title="21.1.3. Authentication"> 21.1.3. Authentication </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.validation');" title="21.1.4. Server-side Validation"> 21.1.4. Server-side Validation </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.validation.json-schema');" title="JSON Schema Validation"> JSON Schema Validation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.validation.query-expression');" title="Query Expression Validation"> Query Expression Validation </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#mongo.mongo-3.misc');" title="21.1.5. Miscellaneous Details"> 21.1.5. Miscellaneous Details </a> </li>
</ul> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#appendix');" title="Appendix"> Appendix </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repositories.namespace-reference');" title="Appendix A: Namespace reference"> Appendix A: Namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#populator.namespace-dao-config');" title="The <repositories /> Element"> The &lt;repositories /&gt; Element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#populator.namespace-reference');" title="Appendix B: Populators namespace reference"> Appendix B: Populators namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#namespace-dao-config');" title="The <populator /> element"> The &lt;populator /&gt; element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repository-query-keywords');" title="Appendix C: Repository query keywords"> Appendix C: Repository query keywords </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Supported query keywords"> Supported query keywords </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#repository-query-return-types');" title="Appendix D: Repository query return types"> Appendix D: Repository query return types </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-mongodb/2.2.1.RELEASE/reference/all.html#');" title="Supported Query Return Types"> Supported Query Return Types </a> </li>
</ul> </li>
</ul> </li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<header class="book-header">
<div class="dropdown pull-right js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-globe"></i>
</a>
<div class="dropdown-menu dropdown-left">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('zh_CN')">中文</button>
</div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('en_US')">English</button>
</div>
</div>
</div>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign up" href="register.html">
<i class="fa fa-sign-in"></i> <span>注册</span>
</a>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign in" href="register.html">
<i class="fa fa-sign-in"></i>
<span>登录</span>
</a>
<a class="btn pull-left js-toolbar-action btn-summary" href="#"><i class="fa fa-align-justify"></i></a>
<div class="dropdown pull-left font-settings js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Font Settings" href="#">
<i class="fa fa-font"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-2 font-reduce">A</button>
<button class="button size-2 font-enlarge">A</button>
</div>
<div class="buttons">
<button class="button size-2 family-serif">Serif</button>
<button class="button size-2 family-sans">Sans</button>
</div>
<div class="buttons">
<button class="button size-3 theme-white">White</button>
<button class="button size-3 theme-sepia">Sepia</button>
<button class="button size-3 theme-night">Night</button>
</div>
</div>
</div>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
<div class="dropdown pull-left js-toolbar-action mobile">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-chevron-down"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<a class="button size-1" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
</div>
</div>
</div>
<div id="autocomplete" class="pull-right"></div>
<span id="toolbar-title"></span>
</header>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal markdown-section">
<div id="content">
<h1>Preface</h1>
<div><ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-6108808167664152" data-ad-slot="6964403648"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<div><div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>© 2008-2019 The original authors.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="openblock partintro">
<div class="content">
<div class="paragraph">
<p>The Spring Data MongoDB project applies core Spring concepts to the development of solutions that use the MongoDB document style data store. We provide a “template” as a high-level abstraction for storing and querying documents. You may notice similarities to the JDBC support provided by the Spring Framework.</p>
</div>
<div class="paragraph">
<p>This document is the reference guide for Spring Data - MongoDB Support. It explains MongoDB module concepts and semantics and syntax for various store namespaces.</p>
</div>
<div class="paragraph">
<p>This section provides some basic introduction to Spring and Document databases. The rest of the document refers only to Spring Data MongoDB features and assumes the user is familiar with MongoDB and Spring concepts.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:first-steps:spring"><a class="anchor" href="#get-started:first-steps:spring"></a>1. Learning Spring</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Data uses Spring framework’s <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html');" target="_blank" rel="noopener noreferrer">core <i class="fa fa-external-link"></i></a> functionality, including:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#beans');" target="_blank" rel="noopener noreferrer">IoC <i class="fa fa-external-link"></i></a> container</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#validation');" target="_blank" rel="noopener noreferrer">type conversion system <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#expressions');" target="_blank" rel="noopener noreferrer">expression language <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/integration.html#jmx');" target="_blank" rel="noopener noreferrer">JMX integration <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/data-access.html#dao-exceptions');" target="_blank" rel="noopener noreferrer">DAO exception hierarchy <i class="fa fa-external-link"></i></a>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>While you need not know the Spring APIs, understanding the concepts behind them is important. At a minimum, the idea behind Inversion of Control (IoC) should be familiar, and you should be familiar with whatever IoC container you choose to use.</p>
</div>
<div class="paragraph">
<p>The core functionality of the MongoDB support can be used directly, with no need to invoke the IoC services of the Spring Container. This is much like <code class="notranslate">JdbcTemplate</code>, which can be used "'standalone'" without any other services of the Spring container. To leverage all the features of Spring Data MongoDB, such as the repository support, you need to configure some parts of the library to use Spring.</p>
</div>
<div class="paragraph">
<p>To learn more about Spring, you can refer to the comprehensive documentation that explains the Spring Framework in detail. There are a lot of articles, blog entries, and books on the subject. See the Spring framework <a href="javascript:window.open('https://spring.io/docs');" target="_blank" rel="noopener noreferrer">home page <i class="fa fa-external-link"></i></a> for more information.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:first-steps:nosql"><a class="anchor" href="#get-started:first-steps:nosql"></a>2. Learning NoSQL and Document databases</h2>
<div class="sectionbody">
<div class="paragraph">
<p>NoSQL stores have taken the storage world by storm. It is a vast domain with a plethora of solutions, terms, and patterns (to make things worse, even the term itself has multiple <a href="javascript:window.open('https://www.google.com/search?q=nosoql+acronym');" target="_blank" rel="noopener noreferrer">meanings <i class="fa fa-external-link"></i></a>). While some of the principles are common, you must be familiar with MongoDB to some degree. The best way to get acquainted is to read the documentation and follow the examples. It usually does not take more then 5-10 minutes to go through them and, especially if you are coming from an RDMBS-only background, these exercises can be an eye opener.</p>
</div>
<div class="paragraph">
<p>The starting point for learning about MongoDB is <a href="javascript:window.open('https://www.mongodb.org/');" target="_blank" rel="noopener noreferrer">www.mongodb.org <i class="fa fa-external-link"></i></a>. Here is a list of other useful resources:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The <a href="javascript:window.open('https://docs.mongodb.org/manual/');" target="_blank" rel="noopener noreferrer">manual <i class="fa fa-external-link"></i></a> introduces MongoDB and contains links to getting started guides, reference documentation, and tutorials.</p> </li>
<li> <p>The <a href="javascript:window.open('https://try.mongodb.org/');" target="_blank" rel="noopener noreferrer">online shell <i class="fa fa-external-link"></i></a> provides a convenient way to interact with a MongoDB instance in combination with the online <a href="javascript:window.open('https://docs.mongodb.org/manual/tutorial/getting-started/');" target="_blank" rel="noopener noreferrer">tutorial. <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>MongoDB <a href="javascript:window.open('https://docs.mongodb.org/ecosystem/drivers/java/');" target="_blank" rel="noopener noreferrer">Java Language Center <i class="fa fa-external-link"></i></a>.</p> </li>
<li> <p>Several <a href="javascript:window.open('https://www.mongodb.org/books');" target="_blank" rel="noopener noreferrer">books <i class="fa fa-external-link"></i></a> you can purchase.</p> </li>
<li> <p>Karl Seguin’s online book: <a href="static/file/mongodb.pdf" target="_blank" rel="noopener noreferrer">The Little MongoDB Book <i class="fa fa-external-link"></i></a>.</p> </li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="requirements"><a class="anchor" href="#requirements"></a>3. Requirements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Spring Data MongoDB 2.x binaries require JDK level 8.0 and above and <a href="javascript:window.open('https://spring.io/docs');" target="_blank" rel="noopener noreferrer">Spring Framework <i class="fa fa-external-link"></i></a> 5.2.1.RELEASE and above.</p>
</div>
<div class="paragraph">
<p>In terms of document stores, you need at least version 2.6 of <a href="javascript:window.open('https://www.mongodb.org/');" target="_blank" rel="noopener noreferrer">MongoDB <i class="fa fa-external-link"></i></a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:help"><a class="anchor" href="#get-started:help"></a>4. Additional Help Resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Learning a new framework is not always straightforward. In this section, we try to provide what we think is an easy-to-follow guide for starting with the Spring Data MongoDB module. However, if you encounter issues or you need advice, feel free to use one of the following links:</p>
</div>
<div id="get-started:help:community" class="dlist">
<dl>
<dt class="hdlist1">
Community Forum
</dt>
<dd>
<p>Spring Data on <a href="javascript:window.open('https://stackoverflow.com/questions/tagged/spring-data');" target="_blank" rel="noopener noreferrer">Stack Overflow <i class="fa fa-external-link"></i></a> is a tag for all Spring Data (not just Document) users to share information and help each other. Note that registration is needed only for posting.</p>
</dd>
</dl>
</div>
<div id="get-started:help:professional" class="dlist">
<dl>
<dt class="hdlist1">
Professional Support
</dt>
<dd>
<p>Professional, from-the-source support, with guaranteed response time, is available from <a href="javascript:window.open('https://pivotal.io/');" target="_blank" rel="noopener noreferrer">Pivotal Sofware, Inc. <i class="fa fa-external-link"></i></a>, the company behind Spring Data and Spring.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:up-to-date"><a class="anchor" href="#get-started:up-to-date"></a>5. Following Development</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For information on the Spring Data Mongo source code repository, nightly builds, and snapshot artifacts, see the Spring Data Mongo <a href="javascript:window.open('https://projects.spring.io/spring-data-mongodb/');" target="_blank" rel="noopener noreferrer">homepage <i class="fa fa-external-link"></i></a>. You can help make Spring Data best serve the needs of the Spring community by interacting with developers through the Community on <a href="javascript:window.open('https://stackoverflow.com/questions/tagged/spring-data');" target="_blank" rel="noopener noreferrer">Stack Overflow <i class="fa fa-external-link"></i></a>. To follow developer activity, look for the mailing list information on the Spring Data Mongo <a href="javascript:window.open('https://projects.spring.io/spring-data-mongodb/');" target="_blank" rel="noopener noreferrer">homepage <i class="fa fa-external-link"></i></a>. If you encounter a bug or want to suggest an improvement, please create a ticket on the Spring Data issue <a href="javascript:window.open('https://jira.spring.io/browse/DATAMONGO');" target="_blank" rel="noopener noreferrer">tracker <i class="fa fa-external-link"></i></a>. To stay up to date with the latest news and announcements in the Spring eco system, subscribe to the Spring Community <a href="javascript:window.open('https://spring.io/');" target="_blank" rel="noopener noreferrer">Portal <i class="fa fa-external-link"></i></a>. You can also follow the Spring <a href="javascript:window.open('https://spring.io/blog');" target="_blank" rel="noopener noreferrer">blog <i class="fa fa-external-link"></i></a> or the project team on Twitter (<a href="javascript:window.open('https://twitter.com/SpringData');" target="_blank" rel="noopener noreferrer">SpringData <i class="fa fa-external-link"></i></a>).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="new-features"><a class="anchor" href="#new-features"></a>6. New &amp; Noteworthy</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="new-features.2-2-0"><a class="anchor" href="#new-features.2-2-0"></a>6.1. What’s New in Spring Data MongoDB 2.2</h3>
<div class="ulist">
<ul>
<li> <p>Compatibility with MongoDB 4.2 deprecating <code class="notranslate">eval</code>, <code class="notranslate">group</code> and <code class="notranslate">geoNear</code> Template API methods.</p> </li>
<li> <p>Extended SpEL aggregation support for MongoDB 3.4 and MongoDB 4.0 operators (see <a href="#mongo.aggregation.projection.expressions">Spring Expression Support in Projection Expressions</a>).</p> </li>
<li> <p><a href="#mongodb.reactive.repositories.queries.type-safe">Querydsl support for reactive repositories</a> via <code class="notranslate">ReactiveQuerydslPredicateExecutor</code>.</p> </li>
<li> <p><a href="#reactive.gridfs">Reactive GridFS support</a>.</p> </li>
<li> <p><a href="#mongodb.repositories.queries.aggregation">Aggregation framework</a> support via repository query methods.</p> </li>
<li> <p>Declarative reactive transactions using <a href="#mongo.transactions.reactive-tx-manager">@Transactional</a>.</p> </li>
<li> <p>Template API delete by entity considers the version property in delete queries.</p> </li>
<li> <p>Repository deletes now throw <code class="notranslate">OptimisticLockingFailureException</code> when a versioned entity cannot be deleted.</p> </li>
<li> <p>Support <code class="notranslate">Range&lt;T&gt;</code> in repository between queries.</p> </li>
<li> <p>Changed behavior of <code class="notranslate">Reactive/MongoOperations#count</code> now limiting the range to count matches within by passing on <em>offset</em> &amp; <em>limit</em> to the server.</p> </li>
<li> <p>Support of array filters in <code class="notranslate">Update</code> operations.</p> </li>
<li> <p><a href="#mongo.jsonSchema.generated">JSON Schema generation</a> from domain types.</p> </li>
<li> <p>SpEL support in for expressions in <code class="notranslate">@Indexed</code>.</p> </li>
<li> <p>Support for <a href="#mapping-usage-indexes.hashed-index">Hashed Indexes</a>.</p> </li>
<li> <p>Annotation-based Collation support through <code class="notranslate">@Document</code> and <code class="notranslate">@Query</code>.</p> </li>
<li> <p><a href="#mongo.query.kotlin-support">Type-safe Queries for Kotlin</a>.</p> </li>
<li> <p>Kotlin extension methods accepting <code class="notranslate">KClass</code> are deprecated now in favor of <code class="notranslate">reified</code> methods.</p> </li>
<li> <p>Kotlin <a href="#kotlin.coroutines">Coroutines</a> support.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.2-1-0"><a class="anchor" href="#new-features.2-1-0"></a>6.2. What’s New in Spring Data MongoDB 2.1</h3>
<div class="ulist">
<ul>
<li> <p>Cursor-based aggregation execution.</p> </li>
<li> <p><a href="#mongo-template.query.distinct">Distinct queries</a> for imperative and reactive Template APIs.</p> </li>
<li> <p>Support for Map/Reduce through the reactive Template API.</p> </li>
<li> <p><a href="#mongo.mongo-3.validation"><code class="notranslate">validator</code> support for collections</a>.</p> </li>
<li> <p><a href="#mongo.jsonSchema"><code class="notranslate">$jsonSchema</code> support</a> for queries and collection creation.</p> </li>
<li> <p><a href="#change-streams">Change Stream support</a> for imperative and reactive drivers.</p> </li>
<li> <p><a href="#tailable-cursors.sync">Tailable cursors</a> for imperative driver.</p> </li>
<li> <p><a href="#mongo.sessions">MongoDB 3.6 Session</a> support for the imperative and reactive Template APIs.</p> </li>
<li> <p><a href="#mongo.transactions">MongoDB 4.0 Transaction</a> support and a MongoDB-specific transaction manager implementation.</p> </li>
<li> <p><a href="#mongodb.repositories.queries.sort">Default sort specifications for repository query methods</a> using <code class="notranslate">@Query(sort=…)</code>.</p> </li>
<li> <p><a href="#mongo-template.find-and-replace">findAndReplace</a> support through imperative and reactive Template APIs.</p> </li>
<li> <p>Deprecation of <code class="notranslate">dropDups</code> in <code class="notranslate">@Indexed</code> and <code class="notranslate">@CompoundIndex</code> as MongoDB server 3.0 and newer do not support <code class="notranslate">dropDups</code> anymore.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.2-0-0"><a class="anchor" href="#new-features.2-0-0"></a>6.3. What’s New in Spring Data MongoDB 2.0</h3>
<div class="ulist">
<ul>
<li> <p>Upgrade to Java 8.</p> </li>
<li> <p>Usage of the <code class="notranslate">Document</code> API, instead of <code class="notranslate">DBObject</code>.</p> </li>
<li> <p><a href="#mongo.reactive">Reactive MongoDB support</a>.</p> </li>
<li> <p><a href="#mongo.reactive.repositories.infinite-streams">Tailable Cursor</a> queries.</p> </li>
<li> <p>Support for aggregation result streaming by using Java 8 <code class="notranslate">Stream</code>.</p> </li>
<li> <p><a href="#mongo.query.fluent-template-api">Fluent Collection API</a> for CRUD and aggregation operations.</p> </li>
<li> <p>Kotlin extensions for Template and Collection APIs.</p> </li>
<li> <p>Integration of collations for collection and index creation and query operations.</p> </li>
<li> <p>Query-by-Example support without type matching.</p> </li>
<li> <p>Support for isolation <code class="notranslate">Update</code> operations.</p> </li>
<li> <p>Tooling support for null-safety by using Spring’s <code class="notranslate">@NonNullApi</code> and <code class="notranslate">@Nullable</code> annotations.</p> </li>
<li> <p>Deprecated cross-store support and removed Log4j appender.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-10-0"><a class="anchor" href="#new-features.1-10-0"></a>6.4. What’s New in Spring Data MongoDB 1.10</h3>
<div class="ulist">
<ul>
<li> <p>Compatible with MongoDB Server 3.4 and the MongoDB Java Driver 3.4.</p> </li>
<li> <p>New annotations for <code class="notranslate">@CountQuery</code>, <code class="notranslate">@DeleteQuery</code>, and <code class="notranslate">@ExistsQuery</code>.</p> </li>
<li> <p>Extended support for MongoDB 3.2 and MongoDB 3.4 aggregation operators (see <a href="#mongo.aggregation.supported-aggregation-operations">Supported Aggregation Operations</a>).</p> </li>
<li> <p>Support for partial filter expression when creating indexes.</p> </li>
<li> <p>Publishing lifecycle events when loading or converting <code class="notranslate">DBRef</code> instances.</p> </li>
<li> <p>Added any-match mode for Query By Example.</p> </li>
<li> <p>Support for <code class="notranslate">$caseSensitive</code> and <code class="notranslate">$diacriticSensitive</code> text search.</p> </li>
<li> <p>Support for GeoJSON Polygon with hole.</p> </li>
<li> <p>Performance improvements by bulk-fetching <code class="notranslate">DBRef</code> instances.</p> </li>
<li> <p>Multi-faceted aggregations using <code class="notranslate">$facet</code>, <code class="notranslate">$bucket</code>, and <code class="notranslate">$bucketAuto</code> with <code class="notranslate">Aggregation</code>.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-9-0"><a class="anchor" href="#new-features.1-9-0"></a>6.5. What’s New in Spring Data MongoDB 1.9</h3>
<div class="ulist">
<ul>
<li> <p>The following annotations have been enabled to build your own composed annotations: <code class="notranslate">@Document</code>, <code class="notranslate">@Id</code>, <code class="notranslate">@Field</code>, <code class="notranslate">@Indexed</code>, <code class="notranslate">@CompoundIndex</code>, <code class="notranslate">@GeoSpatialIndexed</code>, <code class="notranslate">@TextIndexed</code>, <code class="notranslate">@Query</code>, and <code class="notranslate">@Meta</code>.</p> </li>
<li> <p>Support for <a href="#projections">Projections</a> in repository query methods.</p> </li>
<li> <p>Support for <a href="#query-by-example">Query by Example</a>.</p> </li>
<li> <p>Out-of-the-box support for <code class="notranslate">java.util.Currency</code> in object mapping.</p> </li>
<li> <p>Support for the bulk operations introduced in MongoDB 2.6.</p> </li>
<li> <p>Upgrade to Querydsl 4.</p> </li>
<li> <p>Assert compatibility with MongoDB 3.0 and MongoDB Java Driver 3.2 (see: <a href="#mongo.mongo-3">MongoDB 3.0 Support</a>).</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-8-0"><a class="anchor" href="#new-features.1-8-0"></a>6.6. What’s New in Spring Data MongoDB 1.8</h3>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">Criteria</code> offers support for creating <code class="notranslate">$geoIntersects</code>.</p> </li>
<li> <p>Support for <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#expressions');" target="_blank" rel="noopener noreferrer">SpEL expressions <i class="fa fa-external-link"></i></a> in <code class="notranslate">@Query</code>.</p> </li>
<li> <p><code class="notranslate">MongoMappingEvents</code> expose the collection name for which they are issued.</p> </li>
<li> <p>Improved support for <code class="notranslate">&lt;mongo:mongo-client credentials="…" /&gt;</code>.</p> </li>
<li> <p>Improved index creation failure error message.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-7-0"><a class="anchor" href="#new-features.1-7-0"></a>6.7. What’s New in Spring Data MongoDB 1.7</h3>
<div class="ulist">
<ul>
<li> <p>Assert compatibility with MongoDB 3.0 and MongoDB Java Driver 3-beta3 (see: <a href="#mongo.mongo-3">MongoDB 3.0 Support</a>).</p> </li>
<li> <p>Support JSR-310 and ThreeTen back-port date/time types.</p> </li>
<li> <p>Allow <code class="notranslate">Stream</code> as a query method return type (see: <a href="#mongodb.repositories.queries">Query Methods</a>).</p> </li>
<li> <p><a href="javascript:window.open('https://geojson.org/');" target="_blank" rel="noopener noreferrer">GeoJSON <i class="fa fa-external-link"></i></a> support in both domain types and queries (see: <a href="#mongo.geo-json">GeoJSON Support</a>).</p> </li>
<li> <p><code class="notranslate">QueryDslPredicateExcecutor</code> now supports <code class="notranslate">findAll(OrderSpecifier&lt;?&gt;… orders)</code>.</p> </li>
<li> <p>Support calling JavaScript functions with <a href="#mongo.server-side-scripts">Script Operations</a>.</p> </li>
<li> <p>Improve support for <code class="notranslate">CONTAINS</code> keyword on collection-like properties.</p> </li>
<li> <p>Support for <code class="notranslate">$bit</code>, <code class="notranslate">$mul</code>, and <code class="notranslate">$position</code> operators to <code class="notranslate">Update</code>.</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dependencies"><a class="anchor" href="#dependencies"></a>7. Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Due to the different inception dates of individual Spring Data modules, most of them carry different major and minor version numbers. The easiest way to find compatible ones is to rely on the Spring Data Release Train BOM that we ship with the compatible versions defined. In a Maven project, you would declare this dependency in the <code class="notranslate">&lt;dependencyManagement /&gt;</code> section of your POM, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 1. Using the Spring Data release train BOM
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
      &lt;artifactId&gt;spring-data-releasetrain&lt;/artifactId&gt;
      &lt;version&gt;Moore-SR1&lt;/version&gt;
      &lt;scope&gt;import&lt;/scope&gt;
      &lt;type&gt;pom&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre>
</div>
</div>
</div>
</div>
<div id="dependencies.train-names" class="paragraph">
<p>The current release train version is <code class="notranslate">Moore-SR1</code>. The train names ascend alphabetically and the currently available trains are listed <a href="javascript:window.open('https://github.com/spring-projects/spring-data-commons/wiki/Release-planning');" target="_blank" rel="noopener noreferrer">here <i class="fa fa-external-link"></i></a>. The version name follows the following pattern: <code class="notranslate">${name}-${release}</code>, where release can be one of the following:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">BUILD-SNAPSHOT</code>: Current snapshots</p> </li>
<li> <p><code class="notranslate">M1</code>, <code class="notranslate">M2</code>, and so on: Milestones</p> </li>
<li> <p><code class="notranslate">RC1</code>, <code class="notranslate">RC2</code>, and so on: Release candidates</p> </li>
<li> <p><code class="notranslate">RELEASE</code>: GA release</p> </li>
<li> <p><code class="notranslate">SR1</code>, <code class="notranslate">SR2</code>, and so on: Service releases</p> </li>
</ul>
</div>
<div class="paragraph">
<p>A working example of using the BOMs can be found in our <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/bom');" target="_blank" rel="noopener noreferrer">Spring Data examples repository <i class="fa fa-external-link"></i></a>. With that in place, you can declare the Spring Data modules you would like to use without a version in the <code class="notranslate">&lt;dependencies /&gt;</code> block, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 2. Declaring a dependency to a Spring Data module
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
    &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;
  &lt;/dependency&gt;
&lt;dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-boot"><a class="anchor" href="#dependencies.spring-boot"></a>7.1. Dependency Management with Spring Boot</h3>
<div class="paragraph">
<p>Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, configure the property <code class="notranslate">spring-data-releasetrain.version</code> to the <a href="#dependencies.train-names">train name and iteration</a> you would like to use.</p>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-framework"><a class="anchor" href="#dependencies.spring-framework"></a>7.2. Spring Framework</h3>
<div class="paragraph">
<p>The current version of Spring Data modules require Spring Framework in version 5.2.1.RELEASE or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="repositories"><a class="anchor" href="#repositories"></a>8. Working with Spring Data Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.</p>
</div>
<div class="admonitionblock important">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-important" title="Important"></i> </td>
<td class="content">
<div class="paragraph">
<p><em>Spring Data repository documentation and your module</em></p>
</div>
<div class="paragraph">
<p>This chapter explains the core concepts and interfaces of Spring Data repositories. The information in this chapter is pulled from the Spring Data Commons module. It uses the configuration and code samples for the Java Persistence API (JPA) module. You should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. “<a href="#repositories.namespace-reference">Namespace reference</a>” covers XML configuration, which is supported across all Spring Data modules supporting the repository API. “<a href="#repository-query-keywords">Repository query keywords</a>” covers the query method keywords supported by the repository abstraction in general. For detailed information on the specific features of your module, see the chapter on that module of this document.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="repositories.core-concepts"><a class="anchor" href="#repositories.core-concepts"></a>8.1. Core concepts</h3>
<div class="paragraph">
<p>The central interface in the Spring Data repository abstraction is <code class="notranslate">Repository</code>. It takes the domain class to manage as well as the ID type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The <code class="notranslate">CrudRepository</code> provides sophisticated CRUD functionality for the entity class that is being managed.</p>
</div>
<div id="repositories.repository" class="exampleblock">
<div class="title">
Example 3.
<code class="notranslate">CrudRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface CrudRepository&lt;T, ID&gt; extends Repository&lt;T, ID&gt; {

  &lt;S extends T&gt; S save(S entity);      <i class="conum" data-value="1"></i><b>(1)</b>

  Optional&lt;T&gt; findById(ID primaryKey); <i class="conum" data-value="2"></i><b>(2)</b>

  Iterable&lt;T&gt; findAll();               <i class="conum" data-value="3"></i><b>(3)</b>

  long count();                        <i class="conum" data-value="4"></i><b>(4)</b>

  void delete(T entity);               <i class="conum" data-value="5"></i><b>(5)</b>

  boolean existsById(ID primaryKey);   <i class="conum" data-value="6"></i><b>(6)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Saves the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Returns the entity identified by the given ID.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns all entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns the number of entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Deletes the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b class="notranslate">6</b></td>
<td>Indicates whether an entity with the given ID exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> We also provide persistence technology-specific abstractions, such as <code class="notranslate">JpaRepository</code> or <code class="notranslate">MongoRepository</code>. Those interfaces extend <code class="notranslate">CrudRepository</code> and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as <code class="notranslate">CrudRepository</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>On top of the <code class="notranslate">CrudRepository</code>, there is a <code class="notranslate">PagingAndSortingRepository</code> abstraction that adds additional methods to ease paginated access to entities:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 4.
<code class="notranslate">PagingAndSortingRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface PagingAndSortingRepository&lt;T, ID&gt; extends CrudRepository&lt;T, ID&gt; {

  Iterable&lt;T&gt; findAll(Sort sort);

  Page&lt;T&gt; findAll(Pageable pageable);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To access the second page of <code class="notranslate">User</code> by a page size of 20, you could do something like the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">PagingAndSortingRepository&lt;User, Long&gt; repository = // … get access to a bean
Page&lt;User&gt; users = repository.findAll(PageRequest.of(1, 20));</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition to query methods, query derivation for both count and delete queries is available. The following list shows the interface definition for a derived count query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 5. Derived Count Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long countByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following list shows the interface definition for a derived delete query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 6. Derived Delete Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long deleteByLastname(String lastname);

  List&lt;User&gt; removeByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods"><a class="anchor" href="#repositories.query-methods"></a>8.2. Query methods</h3>
<div class="paragraph">
<p>Standard CRUD functionality repositories usually have queries on the underlying datastore. With Spring Data, declaring those queries becomes a four-step process:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Declare an interface extending Repository or one of its subinterfaces and type it to the domain class and ID type that it should handle, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; { … }</code></pre>
</div>
</div> </li>
<li> <p>Declare query methods on the interface.</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
  List&lt;Person&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div> </li>
<li> <p>Set up Spring to create proxy instances for those interfaces, either with <a href="#repositories.create-instances.java-config">JavaConfig</a> or with <a href="#repositories.create-instances">XML configuration</a>.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li> <p>To use Java configuration, create a class similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
class Config { … }</code></pre>
</div>
</div> </li>
<li> <p>To use XML configuration, define a bean similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
     https://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/data/jpa
     https://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

   &lt;jpa:repositories base-package="com.acme.repositories"/&gt;

&lt;/beans&gt;</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The JPA namespace is used in this example. If you use the repository abstraction for any other store, you need to change this to the appropriate namespace declaration of your store module. In other words, you should exchange <code class="notranslate">jpa</code> in favor of, for example, <code class="notranslate">mongodb</code>.</p>
</div>
<div class="paragraph">
<p>+ Also, note that the JavaConfig variant does not configure a package explicitly, because the package of the annotated class is used by default. To customize the package to scan, use one of the <code class="notranslate">basePackage…</code> attributes of the data-store-specific repository’s <code class="notranslate">@Enable${store}Repositories</code>-annotation.</p>
</div> </li>
<li> <p>Inject the repository instance and use it, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">class SomeClient {

  private final PersonRepository repository;

  SomeClient(PersonRepository repository) {
    this.repository = repository;
  }

  void doSomething() {
    List&lt;Person&gt; persons = repository.findByLastname("Matthews");
  }
}</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The sections that follow explain each step in detail:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="#repositories.definition">Defining Repository Interfaces</a></p> </li>
<li> <p><a href="#repositories.query-methods.details">Defining Query Methods</a></p> </li>
<li> <p><a href="#repositories.create-instances">Creating Repository Instances</a></p> </li>
<li> <p><a href="#repositories.custom-implementations">Custom Implementations for Spring Data Repositories</a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="repositories.definition"><a class="anchor" href="#repositories.definition"></a>8.3. Defining Repository Interfaces</h3>
<div class="paragraph">
<p>First, define a domain class-specific repository interface. The interface must extend <code class="notranslate">Repository</code> and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, extend <code class="notranslate">CrudRepository</code> instead of <code class="notranslate">Repository</code>.</p>
</div>
<div class="sect3">
<h4 id="repositories.definition-tuning"><a class="anchor" href="#repositories.definition-tuning"></a>8.3.1. Fine-tuning Repository Definition</h4>
<div class="paragraph">
<p>Typically, your repository interface extends <code class="notranslate">Repository</code>, <code class="notranslate">CrudRepository</code>, or <code class="notranslate">PagingAndSortingRepository</code>. Alternatively, if you do not want to extend Spring Data interfaces, you can also annotate your repository interface with <code class="notranslate">@RepositoryDefinition</code>. Extending <code class="notranslate">CrudRepository</code> exposes a complete set of methods to manipulate your entities. If you prefer to be selective about the methods being exposed, copy the methods you want to expose from <code class="notranslate">CrudRepository</code> into your domain repository.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Doing so lets you define your own abstractions on top of the provided Spring Data Repositories functionality. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following example shows how to selectively expose CRUD methods (<code class="notranslate">findById</code> and <code class="notranslate">save</code>, in this case):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 7. Selectively exposing CRUD methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends Repository&lt;T, ID&gt; {

  Optional&lt;T&gt; findById(ID id);

  &lt;S extends T&gt; S save(S entity);
}

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; {
  User findByEmailAddress(EmailAddress emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the prior example, you defined a common base interface for all your domain repositories and exposed <code class="notranslate">findById(…)</code> as well as <code class="notranslate">save(…)</code>.These methods are routed into the base repository implementation of the store of your choice provided by Spring Data (for example, if you use JPA, the implementation is <code class="notranslate">SimpleJpaRepository</code>), because they match the method signatures in <code class="notranslate">CrudRepository</code>. So the <code class="notranslate">UserRepository</code> can now save users, find individual users by ID, and trigger a query to find <code class="notranslate">Users</code> by email address.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The intermediate repository interface is annotated with <code class="notranslate">@NoRepositoryBean</code>. Make sure you add that annotation to all repository interfaces for which Spring Data should not create instances at runtime. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.multiple-modules"><a class="anchor" href="#repositories.multiple-modules"></a>8.3.2. Using Repositories with Multiple Spring Data Modules</h4>
<div class="paragraph">
<p>Using a unique Spring Data module in your application makes things simple, because all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes, applications require using more than one Spring Data module. In such cases, a repository definition must distinguish between persistence technologies. When it detects multiple repository factories on the class path, Spring Data enters strict repository configuration mode. Strict configuration uses details on the repository or the domain class to decide about Spring Data module binding for a repository definition:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If the repository definition <a href="#repositories.multiple-modules.types">extends the module-specific repository</a>, then it is a valid candidate for the particular Spring Data module.</p> </li>
<li> <p>If the domain class is <a href="#repositories.multiple-modules.annotations">annotated with the module-specific type annotation</a>, then it is a valid candidate for the particular Spring Data module. Spring Data modules accept either third-party annotations (such as JPA’s <code class="notranslate">@Entity</code>) or provide their own annotations (such as <code class="notranslate">@Document</code> for Spring Data MongoDB and Spring Data Elasticsearch).</p> </li>
</ol>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses module-specific interfaces (JPA in this case):</p>
</div>
<div id="repositories.multiple-modules.types" class="exampleblock">
<div class="title">
Example 8. Repository definitions using module-specific interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface MyRepository extends JpaRepository&lt;User, Long&gt; { }

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends JpaRepository&lt;T, ID&gt; { … }

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">MyRepository</code> and <code class="notranslate">UserRepository</code> extend <code class="notranslate">JpaRepository</code> in their type hierarchy. They are valid candidates for the Spring Data JPA module.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses generic interfaces:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 9. Repository definitions using generic interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface AmbiguousRepository extends Repository&lt;User, Long&gt; { … }

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends CrudRepository&lt;T, ID&gt; { … }

interface AmbiguousUserRepository extends MyBaseRepository&lt;User, Long&gt; { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">AmbiguousRepository</code> and <code class="notranslate">AmbiguousUserRepository</code> extend only <code class="notranslate">Repository</code> and <code class="notranslate">CrudRepository</code> in their type hierarchy. While this is perfectly fine when using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses domain classes with annotations:</p>
</div>
<div id="repositories.multiple-modules.annotations" class="exampleblock">
<div class="title">
Example 10. Repository definitions using domain classes with annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; { … }

@Entity
class Person { … }

interface UserRepository extends Repository&lt;User, Long&gt; { … }

@Document
class User { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">PersonRepository</code> references <code class="notranslate">Person</code>, which is annotated with the JPA <code class="notranslate">@Entity</code> annotation, so this repository clearly belongs to Spring Data JPA. <code class="notranslate">UserRepository</code> references <code class="notranslate">User</code>, which is annotated with Spring Data MongoDB’s <code class="notranslate">@Document</code> annotation.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following bad example shows a repository that uses domain classes with mixed annotations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 11. Repository definitions using domain classes with mixed annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface JpaPersonRepository extends Repository&lt;Person, Long&gt; { … }

interface MongoDBPersonRepository extends Repository&lt;Person, Long&gt; { … }

@Entity
@Document
class Person { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example shows a domain class using both JPA and Spring Data MongoDB annotations. It defines two repositories, <code class="notranslate">JpaPersonRepository</code> and <code class="notranslate">MongoDBPersonRepository</code>. One is intended for JPA and the other for MongoDB usage. Spring Data is no longer able to tell the repositories apart, which leads to undefined behavior.</p>
</div>
</div>
</div>
<div class="paragraph">
<p><a href="#repositories.multiple-modules.types">Repository type details</a> and <a href="#repositories.multiple-modules.annotations">distinguishing domain class annotations</a> are used for strict repository configuration to identify repository candidates for a particular Spring Data module. Using multiple persistence technology-specific annotations on the same domain type is possible and enables reuse of domain types across multiple persistence technologies. However, Spring Data can then no longer determine a unique module with which to bind the repository.</p>
</div>
<div class="paragraph">
<p>The last way to distinguish repositories is by scoping repository base packages. Base packages define the starting points for scanning for repository interface definitions, which implies having repository definitions located in the appropriate packages. By default, annotation-driven configuration uses the package of the configuration class. The <a href="#repositories.create-instances.spring">base package in XML-based configuration</a> is mandatory.</p>
</div>
<div class="paragraph">
<p>The following example shows annotation-driven configuration of base packages:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 12. Annotation-driven configuration of base packages
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
class Configuration { … }</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods.details"><a class="anchor" href="#repositories.query-methods.details"></a>8.4. Defining Query Methods</h3>
<div class="paragraph">
<p>The repository proxy has two ways to derive a store-specific query from the method name:</p>
</div>
<div class="ulist">
<ul>
<li> <p>By deriving the query from the method name directly.</p> </li>
<li> <p>By using a manually defined query.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Available options depend on the actual store. However, there must be a strategy that decides what actual query is created. The next section describes the available options.</p>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-lookup-strategies"><a class="anchor" href="#repositories.query-methods.query-lookup-strategies"></a>8.4.1. Query Lookup Strategies</h4>
<div class="paragraph">
<p>The following strategies are available for the repository infrastructure to resolve the query. With XML configuration, you can configure the strategy at the namespace through the <code class="notranslate">query-lookup-strategy</code> attribute. For Java configuration, you can use the <code class="notranslate">queryLookupStrategy</code> attribute of the <code class="notranslate">Enable${store}Repositories</code> annotation. Some strategies may not be supported for particular datastores.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">CREATE</code> attempts to construct a store-specific query from the query method name. The general approach is to remove a given set of well known prefixes from the method name and parse the rest of the method. You can read more about query construction in “<a href="#repositories.query-methods.query-creation">Query Creation</a>”.</p> </li>
<li> <p><code class="notranslate">USE_DECLARED_QUERY</code> tries to find a declared query and throws an exception if cannot find one. The query can be defined by an annotation somewhere or declared by other means. Consult the documentation of the specific store to find available options for that store. If the repository infrastructure does not find a declared query for the method at bootstrap time, it fails.</p> </li>
<li> <p><code class="notranslate">CREATE_IF_NOT_FOUND</code> (default) combines <code class="notranslate">CREATE</code> and <code class="notranslate">USE_DECLARED_QUERY</code>. It looks up a declared query first, and, if no declared query is found, it creates a custom method name-based query. This is the default lookup strategy and, thus, is used if you do not configure anything explicitly. It allows quick query definition by method names but also custom-tuning of these queries by introducing declared queries as needed.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-creation"><a class="anchor" href="#repositories.query-methods.query-creation"></a>8.4.2. Query Creation</h4>
<div class="paragraph">
<p>The query builder mechanism built into Spring Data repository infrastructure is useful for building constraining queries over entities of the repository. The mechanism strips the prefixes <code class="notranslate">find…By</code>, <code class="notranslate">read…By</code>, <code class="notranslate">query…By</code>, <code class="notranslate">count…By</code>, and <code class="notranslate">get…By</code> from the method and starts parsing the rest of it. The introducing clause can contain further expressions, such as a <code class="notranslate">Distinct</code> to set a distinct flag on the query to be created. However, the first <code class="notranslate">By</code> acts as delimiter to indicate the start of the actual criteria. At a very basic level, you can define conditions on entity properties and concatenate them with <code class="notranslate">And</code> and <code class="notranslate">Or</code>. The following example shows how to create a number of queries:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 13. Query creation from method names
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {

  List&lt;Person&gt; findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query
  List&lt;Person&gt; findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List&lt;Person&gt; findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property
  List&lt;Person&gt; findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List&lt;Person&gt; findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query
  List&lt;Person&gt; findByLastnameOrderByFirstnameAsc(String lastname);
  List&lt;Person&gt; findByLastnameOrderByFirstnameDesc(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The actual result of parsing the method depends on the persistence store for which you create the query. However, there are some general things to notice:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The expressions are usually property traversals combined with operators that can be concatenated. You can combine property expressions with <code class="notranslate">AND</code> and <code class="notranslate">OR</code>. You also get support for operators such as <code class="notranslate">Between</code>, <code class="notranslate">LessThan</code>, <code class="notranslate">GreaterThan</code>, and <code class="notranslate">Like</code> for the property expressions. The supported operators can vary by datastore, so consult the appropriate part of your reference documentation.</p> </li>
<li> <p>The method parser supports setting an <code class="notranslate">IgnoreCase</code> flag for individual properties (for example, <code class="notranslate">findByLastnameIgnoreCase(…)</code>) or for all properties of a type that supports ignoring case (usually <code class="notranslate">String</code> instances — for example, <code class="notranslate">findByLastnameAndFirstnameAllIgnoreCase(…)</code>). Whether ignoring cases is supported may vary by store, so consult the relevant sections in the reference documentation for the store-specific query method.</p> </li>
<li> <p>You can apply static ordering by appending an <code class="notranslate">OrderBy</code> clause to the query method that references a property and by providing a sorting direction (<code class="notranslate">Asc</code> or <code class="notranslate">Desc</code>). To create a query method that supports dynamic sorting, see “<a href="#repositories.special-parameters">Special parameter handling</a>”.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-property-expressions"><a class="anchor" href="#repositories.query-methods.query-property-expressions"></a>8.4.3. Property Expressions</h4>
<div class="paragraph">
<p>Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time, you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties. Consider the following method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">List&lt;Person&gt; findByAddressZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assume a <code class="notranslate">Person</code> has an <code class="notranslate">Address</code> with a <code class="notranslate">ZipCode</code>. In that case, the method creates the property traversal <code class="notranslate">x.address.zipCode</code>. The resolution algorithm starts by interpreting the entire part (<code class="notranslate">AddressZipCode</code>) as the property and checks the domain class for a property with that name (uncapitalized). If the algorithm succeeds, it uses that property. If not, the algorithm splits up the source at the camel case parts from the right side into a head and a tail and tries to find the corresponding property — in our example, <code class="notranslate">AddressZip</code> and <code class="notranslate">Code</code>. If the algorithm finds a property with that head, it takes the tail and continues building the tree down from there, splitting the tail up in the way just described. If the first split does not match, the algorithm moves the split point to the left (<code class="notranslate">Address</code>, <code class="notranslate">ZipCode</code>) and continues.</p>
</div>
<div class="paragraph">
<p>Although this should work for most cases, it is possible for the algorithm to select the wrong property. Suppose the <code class="notranslate">Person</code> class has an <code class="notranslate">addressZip</code> property as well. The algorithm would match in the first split round already, choose the wrong property, and fail (as the type of <code class="notranslate">addressZip</code> probably has no <code class="notranslate">code</code> property).</p>
</div>
<div class="paragraph">
<p>To resolve this ambiguity you can use <code class="notranslate">_</code> inside your method name to manually define traversal points. So our method name would be as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">List&lt;Person&gt; findByAddress_ZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).</p>
</div>
</div>
<div class="sect3">
<h4 id="repositories.special-parameters"><a class="anchor" href="#repositories.special-parameters"></a>8.4.4. Special parameter handling</h4>
<div class="paragraph">
<p>To handle parameters in your query, define method parameters as already seen in the preceding examples. Besides that, the infrastructure recognizes certain specific types like <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code>, to apply pagination and sorting to your queries dynamically. The following example demonstrates these features:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 14. Using
<code class="notranslate">Pageable</code>,
<code class="notranslate">Slice</code>, and
<code class="notranslate">Sort</code> in query methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">Page&lt;User&gt; findByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findByLastname(String lastname, Sort sort);

List&lt;User&gt; findByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock important">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-important" title="Important"></i> </td>
<td class="content"> APIs taking <code class="notranslate">Sort</code> and <code class="notranslate">Pageable</code> expect non-<code class="notranslate">null</code> values to be handed into methods. If you don’t want to apply any sorting or pagination use <code class="notranslate">Sort.unsorted()</code> and <code class="notranslate">Pageable.unpaged()</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The first method lets you pass an <code class="notranslate">org.springframework.data.domain.Pageable</code> instance to the query method to dynamically add paging to your statically defined query. A <code class="notranslate">Page</code> knows about the total number of elements and pages available. It does so by the infrastructure triggering a count query to calculate the overall number. As this might be expensive (depending on the store used), you can instead return a <code class="notranslate">Slice</code>. A <code class="notranslate">Slice</code> only knows about whether a next <code class="notranslate">Slice</code> is available, which might be sufficient when walking through a larger result set.</p>
</div>
<div class="paragraph">
<p>Sorting options are handled through the <code class="notranslate">Pageable</code> instance, too. If you only need sorting, add an <code class="notranslate">org.springframework.data.domain.Sort</code> parameter to your method. As you can see, returning a <code class="notranslate">List</code> is also possible. In this case, the additional metadata required to build the actual <code class="notranslate">Page</code> instance is not created (which, in turn, means that the additional count query that would have been necessary is not issued). Rather, it restricts the query to look up only the given range of entities.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> To find out how many pages you get for an entire query, you have to trigger an additional count query. By default, this query is derived from the query you actually trigger. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="repositories.paging-and-sorting"><a class="anchor" href="#repositories.paging-and-sorting"></a>Paging and Sorting</h5>
<div class="paragraph">
<p>Simple sorting expressions can be defined by using property names. Expressions can be concatenated to collect multiple criterias into one expression.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 15. Defining sort expressions
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">Sort sort = Sort.by("firstname").ascending()
  .and(Sort.by("lastname").descending());</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>For a more type-safe way of defining sort expressions, start with the type to define the sort expression for and use method references to define the properties to sort on.</p>
 </div>
<div class="exampleblock">
<div class="title">
Example 16. Defining sort expressions using the type-safe API
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">TypedSort&lt;Person&gt; person = Sort.sort(Person.class);

TypedSort&lt;Person&gt; sort = person.by(Person::getFirstname).ascending()
  .and(person.by(Person::getLastname).descending());</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If your store implementation supports Querydsl, you can also use the metamodel types generated to define sort expressions:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 17. Defining sort expressions using the Querydsl API
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">QSort sort = QSort.by(QPerson.firstname.asc())
  .and(QSort.by(QPerson.lastname.desc()));</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.limit-query-result"><a class="anchor" href="#repositories.limit-query-result"></a>8.4.5. Limiting Query Results</h4>
<div class="paragraph">
<p>The results of query methods can be limited by using the <code class="notranslate">first</code> or <code class="notranslate">top</code> keywords, which can be used interchangeably. An optional numeric value can be appended to <code class="notranslate">top</code> or <code class="notranslate">first</code> to specify the maximum result size to be returned. If the number is left out, a result size of 1 is assumed. The following example shows how to limit the query size:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 18. Limiting the result size of a query with
<code class="notranslate">Top</code> and
<code class="notranslate">First</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">User findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page&lt;User&gt; queryFirst10ByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findTop3ByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findFirst10ByLastname(String lastname, Sort sort);

List&lt;User&gt; findTop10ByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The limiting expressions also support the <code class="notranslate">Distinct</code> keyword. Also, for the queries limiting the result set to one instance, wrapping the result into with the <code class="notranslate">Optional</code> keyword is supported.</p>
</div>
<div class="paragraph">
<p>If pagination or slicing is applied to a limiting query pagination (and the calculation of the number of pages available), it is applied within the limited result.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Limiting the results in combination with dynamic sorting by using a <code class="notranslate">Sort</code> parameter lets you express query methods for the 'K' smallest as well as for the 'K' biggest elements. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.collections-and-iterables"><a class="anchor" href="#repositories.collections-and-iterables"></a>8.4.6. Repository Methods Returning Collections or Iterables</h4>
<div class="paragraph">
<p>Query methods that return multiple results can use standard Java <code class="notranslate">Iterable</code>, <code class="notranslate">List</code>, <code class="notranslate">Set</code>. Beyond that we support returning Spring Data’s <code class="notranslate">Streamable</code>, a custom extension of <code class="notranslate">Iterable</code>, as well as collection types provided by <a href="javascript:window.open('https://www.vavr.io/');" target="_blank" rel="noopener noreferrer">Vavr <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.streamable"><a class="anchor" href="#repositories.collections-and-iterables.streamable"></a>Using Streamable as Query Method Return Type</h5>
<div class="paragraph">
<p><code class="notranslate">Streamable</code> can be used as alternative to <code class="notranslate">Iterable</code> or any collection type. It provides convenience methods to access a non-parallel <code class="notranslate">Stream</code> (missing from <code class="notranslate">Iterable</code>), the ability to directly <code class="notranslate">….filter(…)</code> and <code class="notranslate">….map(…)</code> over the elements and concatenate the <code class="notranslate">Streamable</code> to others:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 19. Using Streamable to combine query method results
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
  Streamable&lt;Person&gt; findByFirstnameContaining(String firstname);
  Streamable&lt;Person&gt; findByLastnameContaining(String lastname);
}

Streamable&lt;Person&gt; result = repository.findByFirstnameContaining("av")
  .and(repository.findByLastnameContaining("ea"));</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.streamable-wrapper"><a class="anchor" href="#repositories.collections-and-iterables.streamable-wrapper"></a>Returning Custom Streamable Wrapper Types</h5>
<div class="paragraph">
<p>Providing dedicated wrapper types for collections is a commonly used pattern to provide API on a query execution result that returns multiple elements. Usually these types are used by invoking a repository method returning a collection-like type and creating an instance of the wrapper type manually. That additional step can be avoided as Spring Data allows to use these wrapper types as query method return types if they meet the following criterias:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>The type implements <code class="notranslate">Streamable</code>.</p> </li>
<li> <p>The type exposes either a constructor or a static factory method named <code class="notranslate">of(…)</code> or <code class="notranslate">valueOf(…)</code> taking <code class="notranslate">Streamable</code> as argument.</p> </li>
</ol>
</div>
<div class="paragraph">
<p>A sample use case looks as follows:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">class Product { <i class="conum" data-value="1"></i><b>(1)</b>
  MonetaryAmount getPrice() { … }
}

@RequiredArgConstructor(staticName = "of")
class Products implements Streamable&lt;Product&gt; { <i class="conum" data-value="2"></i><b>(2)</b>

  private Streamable&lt;Product&gt; streamable;

  public MonetaryAmount getTotal() { <i class="conum" data-value="3"></i><b>(3)</b>
    return streamable.stream() //
      .map(Priced::getPrice)
      .reduce(Money.of(0), MonetaryAmount::add);
  }
}

interface ProductRepository implements Repository&lt;Product, Long&gt; {
  Products findAllByDescriptionContaining(String text); <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>A <code class="notranslate">Product</code> entity that exposes API to access the product’s price.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>A wrapper type for a <code class="notranslate">Streamable&lt;Product&gt;</code> that can be constructed via <code class="notranslate">Products.of(…)</code> (factory method created via the Lombok annotation).</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>The wrapper type exposes additional API calculating new values on the <code class="notranslate">Streamable&lt;Product&gt;</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>That wrapper type can be used as query method return type directly. No need to return <code class="notranslate">Stremable&lt;Product&gt;</code> and manually wrap it in the repository client.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.vavr"><a class="anchor" href="#repositories.collections-and-iterables.vavr"></a>Support for Vavr Collections</h5>
<div class="paragraph">
<p><a href="javascript:window.open('https://www.vavr.io/');" target="_blank" rel="noopener noreferrer">Vavr <i class="fa fa-external-link"></i></a> is a library to embrace functional programming concepts in Java. It ships with a custom set of collection types that can be used as query method return types.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Vavr collection type</th>
<th class="tableblock halign-left valign-top">Used Vavr implementation type</th>
<th class="tableblock halign-left valign-top">Valid Java source types</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Seq</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.List</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Iterable</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Set</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.LinkedHashSet</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Iterable</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Map</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.LinkedHashMap</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Map</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The types in the first column (or subtypes thereof) can be used as quer method return types and will get the types in the second column used as implementation type depending on the Java type of the actual query result (thrid column). Alternatively, <code class="notranslate">Traversable</code> (Vavr the <code class="notranslate">Iterable</code> equivalent) can be declared and we derive the implementation class from the actual return value, i.e. a <code class="notranslate">java.util.List</code> will be turned into a Vavr <code class="notranslate">List</code>/<code class="notranslate">Seq</code>, a <code class="notranslate">java.util.Set</code> becomes a Vavr <code class="notranslate">LinkedHashSet</code>/<code class="notranslate">Set</code> etc.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.nullability"><a class="anchor" href="#repositories.nullability"></a>8.4.7. Null Handling of Repository Methods</h4>
<div class="paragraph">
<p>As of Spring Data 2.0, repository CRUD methods that return an individual aggregate instance use Java 8’s <code class="notranslate">Optional</code> to indicate the potential absence of a value. Besides that, Spring Data supports returning the following wrapper types on query methods:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">com.google.common.base.Optional</code></p> </li>
<li> <p><code class="notranslate">scala.Option</code></p> </li>
<li> <p><code class="notranslate">io.vavr.control.Option</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p>Alternatively, query methods can choose not to use a wrapper type at all. The absence of a query result is then indicated by returning <code class="notranslate">null</code>. Repository methods returning collections, collection alternatives, wrappers, and streams are guaranteed never to return <code class="notranslate">null</code> but rather the corresponding empty representation. See “<a href="#repository-query-return-types">Repository query return types</a>” for details.</p>
</div>
<div class="sect4">
<h5 id="repositories.nullability.annotations"><a class="anchor" href="#repositories.nullability.annotations"></a>Nullability Annotations</h5>
<div class="paragraph">
<p>You can express nullability constraints for repository methods by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#null-safety');" target="_blank" rel="noopener noreferrer">Spring Framework’s nullability annotations <i class="fa fa-external-link"></i></a>. They provide a tooling-friendly approach and opt-in <code class="notranslate">null</code> checks during runtime, as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/javadoc-api/org/springframework/lang/NonNullApi.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNullApi</code> <i class="fa fa-external-link"></i></a>: Used on the package level to declare that the default behavior for parameters and return values is to not accept or produce <code class="notranslate">null</code> values.</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/javadoc-api/org/springframework/lang/NonNull.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNull</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that must not be <code class="notranslate">null</code> (not needed on a parameter and return value where <code class="notranslate">@NonNullApi</code> applies).</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/javadoc-api/org/springframework/lang/Nullable.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Nullable</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that can be <code class="notranslate">null</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Spring annotations are meta-annotated with <a href="javascript:window.open('https://jcp.org/en/jsr/detail?id=305');" target="_blank" rel="noopener noreferrer">JSR 305 <i class="fa fa-external-link"></i></a> annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors such as <a href="javascript:window.open('https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html');" target="_blank" rel="noopener noreferrer">IDEA <i class="fa fa-external-link"></i></a>, <a href="javascript:window.open('https://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm');" target="_blank" rel="noopener noreferrer">Eclipse <i class="fa fa-external-link"></i></a>, and <a href="javascript:window.open('https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types');" target="_blank" rel="noopener noreferrer">Kotlin <i class="fa fa-external-link"></i></a> provide null-safety support in a generic way, without having to hard-code support for Spring annotations. To enable runtime checking of nullability constraints for query methods, you need to activate non-nullability on the package level by using Spring’s <code class="notranslate">@NonNullApi</code> in <code class="notranslate">package-info.java</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 20. Declaring Non-nullability in
<code class="notranslate">package-info.java</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@org.springframework.lang.NonNullApi
package com.acme;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Once non-null defaulting is in place, repository query method invocations get validated at runtime for nullability constraints. If a query execution result violates the defined constraint, an exception is thrown. This happens when the method would return <code class="notranslate">null</code> but is declared as non-nullable (the default with the annotation defined on the package the repository resides in). If you want to opt-in to nullable results again, selectively use <code class="notranslate">@Nullable</code> on individual methods. Using the result wrapper types mentioned at the start of this section continues to work as expected: An empty result is translated into the value that represents absence.</p>
</div>
<div class="paragraph">
<p>The following example shows a number of the techniques just described:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 21. Using different nullability constraints
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package com.acme;                                                       <i class="conum" data-value="1"></i><b>(1)</b>

import org.springframework.lang.Nullable;

interface UserRepository extends Repository&lt;User, Long&gt; {

  User getByEmailAddress(EmailAddress emailAddress);                    <i class="conum" data-value="2"></i><b>(2)</b>

  @Nullable
  User findByEmailAddress(@Nullable EmailAddress emailAdress);          <i class="conum" data-value="3"></i><b>(3)</b>

  Optional&lt;User&gt; findOptionalByEmailAddress(EmailAddress emailAddress); <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The repository resides in a package (or sub-package) for which we have defined non-null behavior.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Throws an <code class="notranslate">EmptyResultDataAccessException</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns <code class="notranslate">null</code> when the query executed does not produce a result. Also accepts <code class="notranslate">null</code> as the value for <code class="notranslate">emailAddress</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns <code class="notranslate">Optional.empty()</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.nullability.kotlin"><a class="anchor" href="#repositories.nullability.kotlin"></a>Nullability in Kotlin-based Repositories</h5>
<div class="paragraph">
<p>Kotlin has the definition of <a href="javascript:window.open('https://kotlinlang.org/docs/reference/null-safety.html');" target="_blank" rel="noopener noreferrer">nullability constraints <i class="fa fa-external-link"></i></a> baked into the language. Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata. Make sure to include the <code class="notranslate">kotlin-reflect</code> JAR in your project to enable introspection of Kotlin’s nullability constraints. Spring Data repositories use the language mechanism to define those constraints to apply the same runtime checks, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 22. Using nullability constraints on Kotlin repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-kotlin hljs" data-lang="kotlin">interface UserRepository : Repository&lt;User, String&gt; {

  fun findByUsername(username: String): User     <i class="conum" data-value="1"></i><b>(1)</b>

  fun findByFirstname(firstname: String?): User? <i class="conum" data-value="2"></i><b>(2)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method defines both the parameter and the result as non-nullable (the Kotlin default). The Kotlin compiler rejects method invocations that pass <code class="notranslate">null</code> to the method. If the query execution yields an empty result, an <code class="notranslate">EmptyResultDataAccessException</code> is thrown.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>This method accepts <code class="notranslate">null</code> for the <code class="notranslate">firstname</code> parameter and returns <code class="notranslate">null</code> if the query execution does not produce a result.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-streaming"><a class="anchor" href="#repositories.query-streaming"></a>8.4.8. Streaming query results</h4>
<div class="paragraph">
<p>The results of query methods can be processed incrementally by using a Java 8 <code class="notranslate">Stream&lt;T&gt;</code> as return type. Instead of wrapping the query results in a <code class="notranslate">Stream</code> data store-specific methods are used to perform the streaming, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 23. Stream the result of a query with Java 8
<code class="notranslate">Stream&lt;T&gt;</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Query("select u from User u")
Stream&lt;User&gt; findAllByCustomQueryAndStream();

Stream&lt;User&gt; readAllByFirstnameNotNull();

@Query("select u from User u")
Stream&lt;User&gt; streamAllPaged(Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> A <code class="notranslate">Stream</code> potentially wraps underlying data store-specific resources and must, therefore, be closed after usage. You can either manually close the <code class="notranslate">Stream</code> by using the <code class="notranslate">close()</code> method or by using a Java 7 <code class="notranslate">try-with-resources</code> block, as shown in the following example: </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 24. Working with a
<code class="notranslate">Stream&lt;T&gt;</code> result in a try-with-resources block
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">try (Stream&lt;User&gt; stream = repository.findAllByCustomQueryAndStream()) {
  stream.forEach(…);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Not all Spring Data modules currently support <code class="notranslate">Stream&lt;T&gt;</code> as a return type. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-async"><a class="anchor" href="#repositories.query-async"></a>8.4.9. Async query results</h4>
<div class="paragraph">
<p>Repository queries can be run asynchronously by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/integration.html#scheduling');" target="_blank" rel="noopener noreferrer">Spring’s asynchronous method execution capability <i class="fa fa-external-link"></i></a>. This means the method returns immediately upon invocation while the actual query execution occurs in a task that has been submitted to a Spring <code class="notranslate">TaskExecutor</code>. Asynchronous query execution is different from reactive query execution and should not be mixed. Refer to store-specific documentation for more details on reactive support. The following example shows a number of asynchronous queries:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Async
Future&lt;User&gt; findByFirstname(String firstname);               <i class="conum" data-value="1"></i><b>(1)</b>

@Async
CompletableFuture&lt;User&gt; findOneByFirstname(String firstname); <i class="conum" data-value="2"></i><b>(2)</b>

@Async
ListenableFuture&lt;User&gt; findOneByLastname(String lastname);    <i class="conum" data-value="3"></i><b>(3)</b></code></pre>
</div>
</div>
<div class="colist arabic">
 <table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Use <code class="notranslate">java.util.concurrent.Future</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Use a Java 8 <code class="notranslate">java.util.concurrent.CompletableFuture</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Use a <code class="notranslate">org.springframework.util.concurrent.ListenableFuture</code> as the return type.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.create-instances"><a class="anchor" href="#repositories.create-instances"></a>8.5. Creating Repository Instances</h3>
<div class="paragraph">
<p>In this section, you create instances and bean definitions for the defined repository interfaces. One way to do so is by using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism, although we generally recommend using Java configuration.</p>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.spring"><a class="anchor" href="#repositories.create-instances.spring"></a>8.5.1. XML configuration</h4>
<div class="paragraph">
<p>Each Spring Data module includes a <code class="notranslate">repositories</code> element that lets you define a base package that Spring scans for you, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 25. Enabling Spring Data repositories via XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    https://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

  &lt;repositories base-package="com.acme.repositories" /&gt;

&lt;/beans:beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, Spring is instructed to scan <code class="notranslate">com.acme.repositories</code> and all its sub-packages for interfaces extending <code class="notranslate">Repository</code> or one of its sub-interfaces. For each interface found, the infrastructure registers the persistence technology-specific <code class="notranslate">FactoryBean</code> to create the appropriate proxies that handle invocations of the query methods. Each bean is registered under a bean name that is derived from the interface name, so an interface of <code class="notranslate">UserRepository</code> would be registered under <code class="notranslate">userRepository</code>. The <code class="notranslate">base-package</code> attribute allows wildcards so that you can define a pattern of scanned packages.</p>
</div>
<div class="sect4">
<h5 id="Using-filters">Using filters</h5>
<div class="paragraph">
<p>By default, the infrastructure picks up every interface extending the persistence technology-specific <code class="notranslate">Repository</code> sub-interface located under the configured base package and creates a bean instance for it. However, you might want more fine-grained control over which interfaces have bean instances created for them. To do so, use <code class="notranslate">&lt;include-filter /&gt;</code> and <code class="notranslate">&lt;exclude-filter /&gt;</code> elements inside the <code class="notranslate">&lt;repositories /&gt;</code> element. The semantics are exactly equivalent to the elements in Spring’s context namespace. For details, see the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#beans-scanning-filters');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for these elements.</p>
</div>
<div class="paragraph">
<p>For example, to exclude certain interfaces from instantiation as repository beans, you could use the following configuration:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 26. Using exclude-filter element
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories base-package="com.acme.repositories"&gt;
  &lt;context:exclude-filter type="regex" expression=".*SomeRepository" /&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example excludes all interfaces ending in <code class="notranslate">SomeRepository</code> from being instantiated.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.java-config"><a class="anchor" href="#repositories.create-instances.java-config"></a>8.5.2. JavaConfig</h4>
<div class="paragraph">
<p>The repository infrastructure can also be triggered by using a store-specific <code class="notranslate">@Enable${store}Repositories</code> annotation on a JavaConfig class. For an introduction into Java-based configuration of the Spring container, see <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#beans-java');" target="_blank" rel="noopener noreferrer">JavaConfig in the Spring reference documentation <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>A sample configuration to enable Spring Data repositories resembles the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 27. Sample annotation based repository configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {

  @Bean
  EntityManagerFactory entityManagerFactory() {
    // …
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the <code class="notranslate">EntityManagerFactory</code> bean. See the sections covering the store-specific configuration. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.standalone"><a class="anchor" href="#repositories.create-instances.standalone"></a>8.5.3. Standalone usage</h4>
<div class="paragraph">
<p>You can also use the repository infrastructure outside of a Spring container — for example, in CDI environments. You still need some Spring libraries in your classpath, but, generally, you can set up repositories programmatically as well. The Spring Data modules that provide repository support ship a persistence technology-specific <code class="notranslate">RepositoryFactory</code> that you can use as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 28. Standalone usage of repository factory
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">RepositoryFactorySupport factory = … // Instantiate factory here
UserRepository repository = factory.getRepository(UserRepository.class);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.custom-implementations"><a class="anchor" href="#repositories.custom-implementations"></a>8.6. Custom Implementations for Spring Data Repositories</h3>
<div class="paragraph">
<p>This section covers repository customization and how fragments form a composite repository.</p>
</div>
<div class="paragraph">
<p>When a query method requires a different behavior or cannot be implemented by query derivation, then it is necessary to provide a custom implementation. Spring Data repositories let you provide custom repository code and integrate it with generic CRUD abstraction and query method functionality.</p>
</div>
<div class="sect3">
<h4 id="repositories.single-repository-behavior"><a class="anchor" href="#repositories.single-repository-behavior"></a>8.6.1. Customizing Individual Repositories</h4>
<div class="paragraph">
<p>To enrich a repository with custom functionality, you must first define a fragment interface and an implementation for the custom functionality, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 29. Interface for custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface CustomizedUserRepository {
  void someCustomMethod(User user);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Then you can let your repository interface additionally extend from the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 30. Implementation of custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  public void someCustomMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The most important part of the class name that corresponds to the fragment interface is the <code class="notranslate">Impl</code> postfix. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The implementation itself does not depend on Spring Data and can be a regular Spring bean. Consequently, you can use standard dependency injection behavior to inject references to other beans (such as a <code class="notranslate">JdbcTemplate</code>), take part in aspects, and so on.</p>
</div>
<div class="paragraph">
<p>You can let your repository interface extend the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 31. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedUserRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Extending the fragment interface with your repository interface combines the CRUD and custom functionality and makes it available to clients.</p>
</div>
<div class="paragraph">
<p>Spring Data repositories are implemented by using fragments that form a repository composition. Fragments are the base repository, functional aspects (such as <a href="#core.extensions.querydsl">QueryDsl</a>), and custom interfaces along with their implementation. Each time you add an interface to your repository interface, you enhance the composition by adding a fragment. The base repository and repository aspect implementations are provided by each Spring Data module.</p>
</div>
<div class="paragraph">
<p>The following example shows custom interfaces and their implementations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 32. Fragments with their implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface HumanRepository {
  void someHumanMethod(User user);
}

class HumanRepositoryImpl implements HumanRepository {

  public void someHumanMethod(User user) {
    // Your custom implementation
  }
}

interface ContactRepository {

  void someContactMethod(User user);

  User anotherContactMethod(User user);
}

class ContactRepositoryImpl implements ContactRepository {

  public void someContactMethod(User user) {
    // Your custom implementation
  }

  public User anotherContactMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows the interface for a custom repository that extends <code class="notranslate">CrudRepository</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 33. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, HumanRepository, ContactRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Repositories may be composed of multiple custom implementations that are imported in the order of their declaration. Custom implementations have a higher priority than the base implementation and repository aspects. This ordering lets you override base repository and aspect methods and resolves ambiguity if two fragments contribute the same method signature. Repository fragments are not limited to use in a single repository interface. Multiple repositories may use a fragment interface, letting you reuse customizations across different repositories.</p>
</div>
<div class="paragraph">
<p>The following example shows a repository fragment and its implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 34. Fragments overriding
<code class="notranslate">save(…)</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface CustomizedSave&lt;T&gt; {
  &lt;S extends T&gt; S save(S entity);
}

class CustomizedSaveImpl&lt;T&gt; implements CustomizedSave&lt;T&gt; {

  public &lt;S extends T&gt; S save(S entity) {
    // Your custom implementation
  }
}</code></pre>
</div> 
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses the preceding repository fragment:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 35. Customized repository interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedSave&lt;User&gt; {
}

interface PersonRepository extends CrudRepository&lt;Person, Long&gt;, CustomizedSave&lt;Person&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="Configuration">Configuration</h5>
<div class="paragraph">
<p>If you use namespace configuration, the repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository. These classes need to follow the naming convention of appending the namespace element’s <code class="notranslate">repository-impl-postfix</code> attribute to the fragment interface name. This postfix defaults to <code class="notranslate">Impl</code>. The following example shows a repository that uses the default postfix and a repository that sets a custom value for the postfix:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 36. Configuration example
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The first configuration in the preceding example tries to look up a class called <code class="notranslate">com.acme.repository.CustomizedUserRepositoryImpl</code> to act as a custom repository implementation. The second example tries to lookup <code class="notranslate">com.acme.repository.CustomizedUserRepositoryMyPostfix</code>.</p>
</div>
<div class="sect5">
<h6 id="repositories.single-repository-behaviour.ambiguity"><a class="anchor" href="#repositories.single-repository-behaviour.ambiguity"></a>Resolution of Ambiguity</h6>
<div class="paragraph">
<p>If multiple implementations with matching class names are found in different packages, Spring Data uses the bean names to identify which one to use.</p>
</div>
<div class="paragraph">
<p>Given the following two custom implementations for the <code class="notranslate">CustomizedUserRepository</code> shown earlier, the first implementation is used. Its bean name is <code class="notranslate">customizedUserRepositoryImpl</code>, which matches that of the fragment interface (<code class="notranslate">CustomizedUserRepository</code>) plus the postfix <code class="notranslate">Impl</code>.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 37. Resolution of amibiguous implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package com.acme.impl.one;

class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package com.acme.impl.two;

@Component("specialCustomImpl")
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you annotate the <code class="notranslate">UserRepository</code> interface with <code class="notranslate">@Component("specialCustom")</code>, the bean name plus <code class="notranslate">Impl</code> then matches the one defined for the repository implementation in <code class="notranslate">com.acme.impl.two</code>, and it is used instead of the first one.</p>
</div>
</div>
<div class="sect5">
<h6 id="repositories.manual-wiring"><a class="anchor" href="#repositories.manual-wiring"></a>Manual Wiring</h6>
<div class="paragraph">
<p>If your custom implementation uses annotation-based configuration and autowiring only, the preceding approach shown works well, because it is treated as any other Spring bean. If your implementation fragment bean needs special wiring, you can declare the bean and name it according to the conventions described in the <a href="#repositories.single-repository-behaviour.ambiguity">preceding section</a>. The infrastructure then refers to the manually defined bean definition by name instead of creating one itself. The following example shows how to manually wire a custom implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 38. Manual wiring of custom implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;beans:bean id="userRepositoryImpl" class="…"&gt;
  &lt;!-- further configuration --&gt;
&lt;/beans:bean&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.customize-base-repository"><a class="anchor" href="#repositories.customize-base-repository"></a>8.6.2. Customize the Base Repository</h4>
<div class="paragraph">
<p>The approach described in the <a href="#repositories.manual-wiring">preceding section</a> requires customization of each repository interfaces when you want to customize the base repository behavior so that all repositories are affected. To instead change behavior for all repositories, you can create an implementation that extends the persistence technology-specific repository base class. This class then acts as a custom base class for the repository proxies, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 39. Custom repository base class
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">class MyRepositoryImpl&lt;T, ID&gt;
  extends SimpleJpaRepository&lt;T, ID&gt; {

  private final EntityManager entityManager;

  MyRepositoryImpl(JpaEntityInformation entityInformation,
                          EntityManager entityManager) {
    super(entityInformation, entityManager);

    // Keep the EntityManager around to used from the newly introduced methods.
    this.entityManager = entityManager;
  }

  @Transactional
  public &lt;S extends T&gt; S save(S entity) {
    // implementation goes here
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td>
<td class="content"> The class needs to have a constructor of the super class which the store-specific repository factory implementation uses. If the repository base class has multiple constructors, override the one taking an <code class="notranslate">EntityInformation</code> plus a store specific infrastructure object (such as an <code class="notranslate">EntityManager</code> or a template class). </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The final step is to make the Spring Data infrastructure aware of the customized repository base class. In Java configuration, you can do so by using the <code class="notranslate">repositoryBaseClass</code> attribute of the <code class="notranslate">@Enable${store}Repositories</code> annotation, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 40. Configuring a custom repository base class using JavaConfig
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>A corresponding attribute is available in the XML namespace, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 41. Configuring a custom repository base class using XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories base-package="com.acme.repository"
     base-class="….MyRepositoryImpl" /&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="core.domain-events"><a class="anchor" href="#core.domain-events"></a>8.7. Publishing Events from Aggregate Roots</h3>
<div class="paragraph">
<p>Entities managed by repositories are aggregate roots. In a Domain-Driven Design application, these aggregate roots usually publish domain events. Spring Data provides an annotation called <code class="notranslate">@DomainEvents</code> that you can use on a method of your aggregate root to make that publication as easy as possible, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 42. Exposing domain events from an aggregate root
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">class AnAggregateRoot {

    @DomainEvents <i class="conum" data-value="1"></i><b>(1)</b>
    Collection&lt;Object&gt; domainEvents() {
        // … return events you want to get published here
    }

    @AfterDomainEventPublication <i class="conum" data-value="2"></i><b>(2)</b>
    void callbackMethod() {
       // … potentially clean up domain events list
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method using <code class="notranslate">@DomainEvents</code> can return either a single event instance or a collection of events. It must not take any arguments.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>After all events have been published, we have a method annotated with <code class="notranslate">@AfterDomainEventPublication</code>. It can be used to potentially clean the list of events to be published (among other uses).</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The methods are called every time one of a Spring Data repository’s <code class="notranslate">save(…)</code> methods is called.</p>
</div>
</div>
<div class="sect2">
<h3 id="core.extensions"><a class="anchor" href="#core.extensions"></a>8.8. Spring Data Extensions</h3>
<div class="paragraph">
<p>This section documents a set of Spring Data extensions that enable Spring Data usage in a variety of contexts. Currently, most of the integration is targeted towards Spring MVC.</p>
</div>
<div class="sect3">
<h4 id="core.extensions.querydsl"><a class="anchor" href="#core.extensions.querydsl"></a>8.8.1. Querydsl Extension</h4>
<div class="paragraph">
<p><a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">Querydsl <i class="fa fa-external-link"></i></a> is a framework that enables the construction of statically typed SQL-like queries through its fluent API.</p>
</div>
<div class="paragraph">
<p>Several Spring Data modules offer integration with Querydsl through <code class="notranslate">QuerydslPredicateExecutor</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 43. QuerydslPredicateExecutor interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface QuerydslPredicateExecutor&lt;T&gt; {

  Optional&lt;T&gt; findById(Predicate predicate);  <i class="conum" data-value="1"></i><b>(1)</b>

  Iterable&lt;T&gt; findAll(Predicate predicate);   <i class="conum" data-value="2"></i><b>(2)</b>

  long count(Predicate predicate);            <i class="conum" data-value="3"></i><b>(3)</b>

  boolean exists(Predicate predicate);        <i class="conum" data-value="4"></i><b>(4)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Finds and returns a single entity matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Finds and returns all entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns the number of entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns whether an entity that matches the <code class="notranslate">Predicate</code> exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>To make use of Querydsl support, extend <code class="notranslate">QuerydslPredicateExecutor</code> on your repository interface, as shown in the following example</p>
</div>
<div class="exampleblock">
<div class="title">
Example 44. Querydsl integration on repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, QuerydslPredicateExecutor&lt;User&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example lets you write typesafe queries using Querydsl <code class="notranslate">Predicate</code> instances, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">Predicate predicate = user.firstname.equalsIgnoreCase("dave")
	.and(user.lastname.startsWithIgnoreCase("mathews"));

userRepository.findAll(predicate);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.web"><a class="anchor" href="#core.web"></a>8.8.2. Web support</h4>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> This section contains the documentation for the Spring Data web support as it is implemented in the current (and later) versions of Spring Data Commons. As the newly introduced support changes many things, we kept the documentation of the former behavior in <a href="#web.legacy">[web.legacy]</a>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Spring Data modules that support the repository programming model ship with a variety of web support. The web related components require Spring MVC JARs to be on the classpath. Some of them even provide integration with <a href="javascript:window.open('https://github.com/SpringSource/spring-hateoas');" target="_blank" rel="noopener noreferrer">Spring HATEOAS <i class="fa fa-external-link"></i></a>. In general, the integration support is enabled by using the <code class="notranslate">@EnableSpringDataWebSupport</code> annotation in your JavaConfig configuration class, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 45. Enabling Spring Data web support
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code class="notranslate">@EnableSpringDataWebSupport</code> annotation registers a few components we will discuss in a bit. It will also detect Spring HATEOAS on the classpath and register integration components for it as well if present.</p>
</div>
<div class="paragraph">
<p>Alternatively, if you use XML configuration, register either <code class="notranslate">SpringDataWebConfiguration</code> or <code class="notranslate">HateoasAwareSpringDataWebConfiguration</code> as Spring beans, as shown in the following example (for <code class="notranslate">SpringDataWebConfiguration</code>):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 46. Enabling Spring Data web support in XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;bean class="org.springframework.data.web.config.SpringDataWebConfiguration" /&gt;

&lt;!-- If you use Spring HATEOAS, register this one *instead* of the former --&gt;
&lt;bean class="org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.basic"><a class="anchor" href="#core.web.basic"></a>Basic Web Support</h5>
<div class="paragraph">
<p>The configuration shown in the <a href="#core.web">previous section</a> registers a few basic components:</p>
</div>
<div class="ulist">
<ul>
<li> <p>A <a href="#core.web.basic.domain-class-converter"><code class="notranslate">DomainClassConverter</code></a> to let Spring MVC resolve instances of repository-managed domain classes from request parameters or path variables.</p> </li>
<li> <p><a href="#core.web.basic.paging-and-sorting"><code class="notranslate">HandlerMethodArgumentResolver</code></a> implementations to let Spring MVC resolve <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> instances from request parameters.</p> </li>
</ul>
</div>
<div class="sect5">
<h6 id="core.web.basic.domain-class-converter"><a class="anchor" href="#core.web.basic.domain-class-converter"></a><code class="notranslate">DomainClassConverter</code></h6>
<div class="paragraph">
<p>The <code class="notranslate">DomainClassConverter</code> lets you use domain types in your Spring MVC controller method signatures directly, so that you need not manually lookup the instances through the repository, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 47. A Spring MVC controller using domain types in method signatures
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  @RequestMapping("/{id}")
  String showUserForm(@PathVariable("id") User user, Model model) {

    model.addAttribute("user", user);
    return "userForm";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As you can see, the method receives a <code class="notranslate">User</code> instance directly, and no further lookup is necessary. The instance can be resolved by letting Spring MVC convert the path variable into the <code class="notranslate">id</code> type of the domain class first and eventually access the instance through calling <code class="notranslate">findById(…)</code> on the repository instance registered for the domain type.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Currently, the repository has to implement <code class="notranslate">CrudRepository</code> to be eligible to be discovered for conversion. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect5">
<h6 id="core.web.basic.paging-and-sorting"><a class="anchor" href="#core.web.basic.paging-and-sorting"></a>HandlerMethodArgumentResolvers for Pageable and Sort</h6>
<div class="paragraph">
<p>The configuration snippet shown in the <a href="#core.web.basic.domain-class-converter">previous section</a> also registers a <code class="notranslate">PageableHandlerMethodArgumentResolver</code> as well as an instance of <code class="notranslate">SortHandlerMethodArgumentResolver</code>. The registration enables <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> as valid controller method arguments, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 48. Using Pageable as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  private final UserRepository repository;

  UserController(UserRepository repository) {
    this.repository = repository;
  }

  @RequestMapping
  String showUsers(Model model, Pageable pageable) {

    model.addAttribute("users", repository.findAll(pageable));
    return "users";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding method signature causes Spring MVC try to derive a <code class="notranslate">Pageable</code> instance from the request parameters by using the following default configuration:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 1. Request parameters evaluated for
<code class="notranslate">Pageable</code> instances
</caption>
<colgroup>
<col>
 <col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">page</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Page you want to retrieve. 0-indexed and defaults to 0.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">size</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Size of the page you want to retrieve. Defaults to 20.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">sort</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Properties that should be sorted by in the format <code class="notranslate">property,property(,ASC|DESC)</code>. Default sort direction is ascending. Use multiple <code class="notranslate">sort</code> parameters if you want to switch directions — for example, <code class="notranslate">?sort=firstname&amp;sort=lastname,asc</code>.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>To customize this behavior, register a bean implementing the <code class="notranslate">PageableHandlerMethodArgumentResolverCustomizer</code> interface or the <code class="notranslate">SortHandlerMethodArgumentResolverCustomizer</code> interface, respectively. Its <code class="notranslate">customize()</code> method gets called, letting you change settings, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {
    return s -&gt; s.setPropertyDelimiter("&lt;--&gt;");
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If setting the properties of an existing <code class="notranslate">MethodArgumentResolver</code> is not sufficient for your purpose, extend either <code class="notranslate">SpringDataWebConfiguration</code> or the HATEOAS-enabled equivalent, override the <code class="notranslate">pageableResolver()</code> or <code class="notranslate">sortResolver()</code> methods, and import your customized configuration file instead of using the <code class="notranslate">@Enable</code> annotation.</p>
</div>
<div class="paragraph">
<p>If you need multiple <code class="notranslate">Pageable</code> or <code class="notranslate">Sort</code> instances to be resolved from the request (for multiple tables, for example), you can use Spring’s <code class="notranslate">@Qualifier</code> annotation to distinguish one from another. The request parameters then have to be prefixed with <code class="notranslate">${qualifier}_</code>. The followig example shows the resulting method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">String showUsers(Model model,
      @Qualifier("thing1") Pageable first,
      @Qualifier("thing2") Pageable second) { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p>you have to populate <code class="notranslate">thing1_page</code> and <code class="notranslate">thing2_page</code> and so on.</p>
</div>
<div class="paragraph">
<p>The default <code class="notranslate">Pageable</code> passed into the method is equivalent to a <code class="notranslate">PageRequest.of(0, 20)</code> but can be customized by using the <code class="notranslate">@PageableDefault</code> annotation on the <code class="notranslate">Pageable</code> parameter.</p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.pageables"><a class="anchor" href="#core.web.pageables"></a>Hypermedia Support for Pageables</h5>
<div class="paragraph">
<p>Spring HATEOAS ships with a representation model class (<code class="notranslate">PagedResources</code>) that allows enriching the content of a <code class="notranslate">Page</code> instance with the necessary <code class="notranslate">Page</code> metadata as well as links to let the clients easily navigate the pages. The conversion of a Page to a <code class="notranslate">PagedResources</code> is done by an implementation of the Spring HATEOAS <code class="notranslate">ResourceAssembler</code> interface, called the <code class="notranslate">PagedResourcesAssembler</code>. The following example shows how to use a <code class="notranslate">PagedResourcesAssembler</code> as a controller method argument:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 49. Using a PagedResourcesAssembler as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Controller
class PersonController {

  @Autowired PersonRepository repository;

  @RequestMapping(value = "/persons", method = RequestMethod.GET)
  HttpEntity&lt;PagedResources&lt;Person&gt;&gt; persons(Pageable pageable,
    PagedResourcesAssembler assembler) {

    Page&lt;Person&gt; persons = repository.findAll(pageable);
    return new ResponseEntity&lt;&gt;(assembler.toResources(persons), HttpStatus.OK);
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Enabling the configuration as shown in the preceding example lets the <code class="notranslate">PagedResourcesAssembler</code> be used as a controller method argument. Calling <code class="notranslate">toResources(…)</code> on it has the following effects:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The content of the <code class="notranslate">Page</code> becomes the content of the <code class="notranslate">PagedResources</code> instance.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> object gets a <code class="notranslate">PageMetadata</code> instance attached, and it is populated with information from the <code class="notranslate">Page</code> and the underlying <code class="notranslate">PageRequest</code>.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> may get <code class="notranslate">prev</code> and <code class="notranslate">next</code> links attached, depending on the page’s state. The links point to the URI to which the method maps. The pagination parameters added to the method match the setup of the <code class="notranslate">PageableHandlerMethodArgumentResolver</code> to make sure the links can be resolved later.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Assume we have 30 Person instances in the database. You can now trigger a request (<code class="notranslate">GET <a href="javascript:window.open('http://localhost:8080/persons');" class="bare" target="_blank" rel="noopener noreferrer">http://localhost:8080/persons <i class="fa fa-external-link"></i></a></code>) and see output similar to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-javascript hljs" data-lang="javascript">{ "links" : [ { "rel" : "next",
                "href" : "http://localhost:8080/persons?page=1&amp;size=20 }
  ],
  "content" : [
     … // 20 Person instances rendered here
  ],
  "pageMetadata" : {
    "size" : 20,
    "totalElements" : 30,
    "totalPages" : 2,
    "number" : 0
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You see that the assembler produced the correct URI and also picked up the default configuration to resolve the parameters into a <code class="notranslate">Pageable</code> for an upcoming request. This means that, if you change that configuration, the links automatically adhere to the change. By default, the assembler points to the controller method it was invoked in, but that can be customized by handing in a custom <code class="notranslate">Link</code> to be used as base to build the pagination links, which overloads the <code class="notranslate">PagedResourcesAssembler.toResource(…)</code> method.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.binding"><a class="anchor" href="#core.web.binding"></a>Web Databinding Support</h5>
<div class="paragraph">
<p>Spring Data projections (described in <a href="#projections">Projections</a>) can be used to bind incoming request payloads by either using <a href="javascript:window.open('https://goessner.net/articles/JsonPath/');" target="_blank" rel="noopener noreferrer">JSONPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://github.com/json-path/JsonPath');" target="_blank" rel="noopener noreferrer">Jayway JsonPath <i class="fa fa-external-link"></i></a> or <a href="javascript:window.open('https://www.w3.org/TR/xpath-31/');" target="_blank" rel="noopener noreferrer">XPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://xmlbeam.org/');" target="_blank" rel="noopener noreferrer">XmlBeam <i class="fa fa-external-link"></i></a>), as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 50. HTTP payload binding using JSONPath or XPath expressions
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@ProjectedPayload
public interface UserPayload {

  @XBRead("//firstname")
  @JsonPath("$..firstname")
  String getFirstname();

  @XBRead("/lastname")
  @JsonPath({ "$.lastname", "$.user.lastname" })
  String getLastname();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The type shown in the preceding example can be used as a Spring MVC handler method argument or by using <code class="notranslate">ParameterizedTypeReference</code> on one of <code class="notranslate">RestTemplate</code>'s methods. The preceding method declarations would try to find <code class="notranslate">firstname</code> anywhere in the given document. The <code class="notranslate">lastname</code> XML lookup is performed on the top-level of the incoming document. The JSON variant of that tries a top-level <code class="notranslate">lastname</code> first but also tries <code class="notranslate">lastname</code> nested in a <code class="notranslate">user</code> sub-document if the former does not return a value. That way, changes in the structure of the source document can be mitigated easily without having clients calling the exposed methods (usually a drawback of class-based payload binding).</p>
</div>
<div class="paragraph">
<p>Nested projections are supported as described in <a href="#projections">Projections</a>. If the method returns a complex, non-interface type, a Jackson <code class="notranslate">ObjectMapper</code> is used to map the final value.</p>
</div>
<div class="paragraph">
<p>For Spring MVC, the necessary converters are registered automatically as soon as <code class="notranslate">@EnableSpringDataWebSupport</code> is active and the required dependencies are available on the classpath. For usage with <code class="notranslate">RestTemplate</code>, register a <code class="notranslate">ProjectingJackson2HttpMessageConverter</code> (JSON) or <code class="notranslate">XmlBeamHttpMessageConverter</code> manually.</p>
</div>
<div class="paragraph">
<p>For more information, see the <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/web/projection');" target="_blank" rel="noopener noreferrer">web projection example <i class="fa fa-external-link"></i></a> in the canonical <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples');" target="_blank" rel="noopener noreferrer">Spring Data Examples repository <i class="fa fa-external-link"></i></a>.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.type-safe"><a class="anchor" href="#core.web.type-safe"></a>Querydsl Web Support</h5>
<div class="paragraph">
<p>For those stores having <a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">QueryDSL <i class="fa fa-external-link"></i></a> integration, it is possible to derive queries from the attributes contained in a <code class="notranslate">Request</code> query string.</p>
</div>
<div class="paragraph">
<p>Consider the following query string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-text hljs" data-lang="text">?firstname=Dave&amp;lastname=Matthews</code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the <code class="notranslate">User</code> object from previous examples, a query string can be resolved to the following value by using the <code class="notranslate">QuerydslPredicateArgumentResolver</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-text hljs" data-lang="text">QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The feature is automatically enabled, along with <code class="notranslate">@EnableSpringDataWebSupport</code>, when Querydsl is found on the classpath. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Adding a <code class="notranslate">@QuerydslPredicate</code> to the method signature provides a ready-to-use <code class="notranslate">Predicate</code>, which can be run by using the <code class="notranslate">QuerydslPredicateExecutor</code>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td>
<td class="content"> Type information is typically resolved from the method’s return type. Since that information does not necessarily match the domain type, it might be a good idea to use the <code class="notranslate">root</code> attribute of <code class="notranslate">QuerydslPredicate</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following exampe shows how to use <code class="notranslate">@QuerydslPredicate</code> in a method signature:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Controller
class UserController {

  @Autowired UserRepository repository;

  @RequestMapping(value = "/", method = RequestMethod.GET)
  String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,    <i class="conum" data-value="1"></i><b>(1)</b>
          Pageable pageable, @RequestParam MultiValueMap&lt;String, String&gt; parameters) {

    model.addAttribute("users", repository.findAll(predicate, pageable));

    return "index";
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Resolve query string arguments to matching <code class="notranslate">Predicate</code> for <code class="notranslate">User</code>.</td>
</tr>
 </tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The default binding is as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">Object</code> on simple properties as <code class="notranslate">eq</code>.</p> </li>
<li> <p><code class="notranslate">Object</code> on collection like properties as <code class="notranslate">contains</code>.</p> </li>
<li> <p><code class="notranslate">Collection</code> on simple properties as <code class="notranslate">in</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Those bindings can be customized through the <code class="notranslate">bindings</code> attribute of <code class="notranslate">@QuerydslPredicate</code> or by making use of Java 8 <code class="notranslate">default methods</code> and adding the <code class="notranslate">QuerydslBinderCustomizer</code> method to the repository interface.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">interface UserRepository extends CrudRepository&lt;User, String&gt;,
                                 QuerydslPredicateExecutor&lt;User&gt;,                <i class="conum" data-value="1"></i><b>(1)</b>
                                 QuerydslBinderCustomizer&lt;QUser&gt; {               <i class="conum" data-value="2"></i><b>(2)</b>

  @Override
  default void customize(QuerydslBindings bindings, QUser user) {

    bindings.bind(user.username).first((path, value) -&gt; path.contains(value))    <i class="conum" data-value="3"></i><b>(3)</b>
    bindings.bind(String.class)
      .first((StringPath path, String value) -&gt; path.containsIgnoreCase(value)); <i class="conum" data-value="4"></i><b>(4)</b>
    bindings.excluding(user.password);                                           <i class="conum" data-value="5"></i><b>(5)</b>
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td><code class="notranslate">QuerydslPredicateExecutor</code> provides access to specific finder methods for <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td><code class="notranslate">QuerydslBinderCustomizer</code> defined on the repository interface is automatically picked up and shortcuts <code class="notranslate">@QuerydslPredicate(bindings=…)</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Define the binding for the <code class="notranslate">username</code> property to be a simple <code class="notranslate">contains</code> binding.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Define the default binding for <code class="notranslate">String</code> properties to be a case-insensitive <code class="notranslate">contains</code> match.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Exclude the <code class="notranslate">password</code> property from <code class="notranslate">Predicate</code> resolution.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.repository-populators"><a class="anchor" href="#core.repository-populators"></a>8.8.3. Repository Populators</h4>
<div class="paragraph">
<p>If you work with the Spring JDBC module, you are probably familiar with the support to populate a <code class="notranslate">DataSource</code> with SQL scripts. A similar abstraction is available on the repositories level, although it does not use SQL as the data definition language because it must be store-independent. Thus, the populators support XML (through Spring’s OXM abstraction) and JSON (through Jackson) to define data with which to populate the repositories.</p>
</div>
<div class="paragraph">
<p>Assume you have a file <code class="notranslate">data.json</code> with the following content:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 51. Data defined in JSON
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-javascript hljs" data-lang="javascript">[ { "_class" : "com.acme.Person",
 "firstname" : "Dave",
  "lastname" : "Matthews" },
  { "_class" : "com.acme.Person",
 "firstname" : "Carter",
  "lastname" : "Beauford" } ]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You can populate your repositories by using the populator elements of the repository namespace provided in Spring Data Commons. To populate the preceding data to your PersonRepository, declare a populator similar to the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 52. Declaring a Jackson repository populator
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    https://www.springframework.org/schema/data/repository/spring-repository.xsd"&gt;

  &lt;repository:jackson2-populator locations="classpath:data.json" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding declaration causes the <code class="notranslate">data.json</code> file to be read and deserialized by a Jackson <code class="notranslate">ObjectMapper</code>.</p>
</div>
<div class="paragraph">
<p>The type to which the JSON object is unmarshalled is determined by inspecting the <code class="notranslate">_class</code> attribute of the JSON document. The infrastructure eventually selects the appropriate repository to handle the object that was deserialized.</p>
</div>
<div class="paragraph">
<p>To instead use XML to define the data the repositories should be populated with, you can use the <code class="notranslate">unmarshaller-populator</code> element. You configure it to use one of the XML marshaller options available in Spring OXM. See the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/data-access.html#oxm');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for details. The following example shows how to unmarshal a repository populator with JAXB:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 53. Declaring an unmarshalling repository populator (using JAXB)
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xmlns:oxm="http://www.springframework.org/schema/oxm"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    https://www.springframework.org/schema/data/repository/spring-repository.xsd
    http://www.springframework.org/schema/oxm
    https://www.springframework.org/schema/oxm/spring-oxm.xsd"&gt;

  &lt;repository:unmarshaller-populator locations="classpath:data.json"
    unmarshaller-ref="unmarshaller" /&gt;

  &lt;oxm:jaxb2-marshaller contextPath="com.acme" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h2 id="reference" class="sect0"><a class="anchor" href="#reference"></a>Reference Documentation</h2>
<div class="sect1">
<h2 id="introduction"><a class="anchor" href="#introduction"></a>9. Introduction</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="9.1.-Document-Structure">9.1. Document Structure</h3>
<div class="paragraph">
<p>This part of the reference documentation explains the core functionality offered by Spring Data MongoDB.</p>
</div>
<div class="paragraph">
<p>“<a href="#mongo.core">MongoDB support</a>” introduces the MongoDB module feature set.</p>
</div>
<div class="paragraph">
<p>“<a href="#mongo.repositories">MongoDB Repositories</a>” introduces the repository support for MongoDB.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="mongo.core"><a class="anchor" href="#mongo.core"></a>10. MongoDB support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The MongoDB support contains a wide range of features:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Spring configuration support with Java-based <code class="notranslate">@Configuration</code> classes or an XML namespace for a Mongo driver instance and replica sets.</p> </li>
<li> <p><code class="notranslate">MongoTemplate</code> helper class that increases productivity when performing common Mongo operations. Includes integrated object mapping between documents and POJOs.</p> </li>
<li> <p>Exception translation into Spring’s portable Data Access Exception hierarchy.</p> </li>
<li> <p>Feature-rich Object Mapping integrated with Spring’s Conversion Service.</p> </li>
<li> <p>Annotation-based mapping metadata that is extensible to support other metadata formats.</p> </li>
<li> <p>Persistence and mapping lifecycle events.</p> </li>
<li> <p>Java-based Query, Criteria, and Update DSLs.</p> </li>
<li> <p>Automatic implementation of Repository interfaces, including support for custom finder methods.</p> </li>
<li> <p>QueryDSL integration to support type-safe queries.</p> </li>
<li> <p>Cross-store persistence support for JPA Entities with fields transparently persisted and retrieved with MongoDB (deprecated - to be removed without replacement).</p> </li>
<li> <p>GeoSpatial integration.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>For most tasks, you should use <code class="notranslate">MongoTemplate</code> or the Repository support, which both leverage the rich mapping functionality. <code class="notranslate">MongoTemplate</code> is the place to look for accessing functionality such as incrementing counters or ad-hoc CRUD operations. <code class="notranslate">MongoTemplate</code> also provides callback methods so that it is easy for you to get the low-level API artifacts, such as <code class="notranslate">com.mongodb.client.MongoDatabase</code>, to communicate directly with MongoDB. The goal with naming conventions on various API artifacts is to copy those in the base MongoDB Java driver so you can easily map your existing knowledge onto the Spring APIs.</p>
</div>
<div class="sect2">
<h3 id="mongodb-getting-started"><a class="anchor" href="#mongodb-getting-started"></a>10.1. Getting Started</h3>
<div class="paragraph">
<p>An easy way to bootstrap setting up a working environment is to create a Spring-based project in <a href="javascript:window.open('https://spring.io/tools/sts');" target="_blank" rel="noopener noreferrer">STS <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>First, you need to set up a running MongoDB server. Refer to the <a href="javascript:window.open('https://docs.mongodb.org/manual/core/introduction/');" target="_blank" rel="noopener noreferrer">MongoDB Quick Start guide <i class="fa fa-external-link"></i></a> for an explanation on how to startup a MongoDB instance. Once installed, starting MongoDB is typically a matter of running the following command: <code class="notranslate">${MONGO_HOME}/bin/mongod</code></p>
</div>
<div class="paragraph">
<p>To create a Spring project in STS:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Go to File → New → Spring Template Project → Simple Spring Utility Project, and press Yes when prompted. Then enter a project and a package name, such as <code class="notranslate">org.spring.mongodb.example</code>. .Add the following to the pom.xml files <code class="notranslate">dependencies</code> element:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencies&gt;

  &lt;!-- other dependency elements omitted --&gt;

  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
    &lt;artifactId&gt;spring-data-mongodb&lt;/artifactId&gt;
    &lt;version&gt;2.2.1.RELEASE&lt;/version&gt;
  &lt;/dependency&gt;

&lt;/dependencies&gt;</code></pre>
</div>
</div> </li>
<li> <p>Change the version of Spring in the pom.xml to be</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;spring.framework.version&gt;5.2.1.RELEASE&lt;/spring.framework.version&gt;</code></pre>
</div>
</div> </li>
<li> <p>Add the following location of the Spring Milestone repository for Maven to your <code class="notranslate">pom.xml</code> such that it is at the same level of your <code class="notranslate">&lt;dependencies/&gt;</code> element:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories&gt;
  &lt;repository&gt;
    &lt;id&gt;spring-milestone&lt;/id&gt;
    &lt;name&gt;Spring Maven MILESTONE Repository&lt;/name&gt;
    &lt;url&gt;https://repo.spring.io/libs-milestone&lt;/url&gt;
  &lt;/repository&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The repository is also <a href="javascript:window.open('https://repo.spring.io/milestone/org/springframework/data/');" target="_blank" rel="noopener noreferrer">browseable here <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>You may also want to set the logging level to <code class="notranslate">DEBUG</code> to see some additional information. To do so, edit the <code class="notranslate">log4j.properties</code> file to have the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code>log4j.category.org.springframework.data.mongodb=DEBUG
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then you can create a <code class="notranslate">Person</code> class to persist:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package org.spring.mongodb.example;

public class Person {

  private String id;
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getId() {
    return id;
  }
  public String getName() {
    return name;
  }
  public int getAge() {
    return age;
  }

  @Override
  public String toString() {
    return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You also need a main application to run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package org.spring.mongodb.example;

import static org.springframework.data.mongodb.core.query.Criteria.where;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;

import com.mongodb.client.MongoClients;

public class MongoApp {

  private static final Log log = LogFactory.getLog(MongoApp.class);

  public static void main(String[] args) throws Exception {

    MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "database");
    mongoOps.insert(new Person("Joe", 34));

    log.info(mongoOps.findOne(new Query(where("name").is("Joe")), Person.class));

    mongoOps.dropCollection("person");
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you run the main program, the preceding examples produce the following output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code>10:01:32,062 DEBUG apping.MongoPersistentEntityIndexCreator:  80 - Analyzing class class org.spring.example.Person for index information.
10:01:32,265 DEBUG ramework.data.mongodb.core.MongoTemplate: 631 - insert Document containing fields: [_class, age, name] in collection: Person
10:01:32,765 DEBUG ramework.data.mongodb.core.MongoTemplate:1243 - findOne using query: { "name" : "Joe"} in db.collection: database.Person
10:01:32,953  INFO      org.spring.mongodb.example.MongoApp:  25 - Person [id=4ddbba3c0be56b7e1b210166, name=Joe, age=34]
10:01:32,984 DEBUG ramework.data.mongodb.core.MongoTemplate: 375 - Dropped collection [database.person]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Even in this simple example, there are few things to notice:</p>
</div>
<div class="ulist">
<ul>
<li> <p>You can instantiate the central helper class of Spring Mongo, <a href="#mongo-template"><code class="notranslate">MongoTemplate</code></a>, by using the standard <code class="notranslate">com.mongodb.MongoClient</code> object and the name of the database to use.</p> </li>
<li> <p>The mapper works against standard POJO objects without the need for any additional metadata (though you can optionally provide that information. See <a href="#mapping-chapter">here</a>.).</p> </li>
<li> <p>Conventions are used for handling the <code class="notranslate">id</code> field, converting it to be an <code class="notranslate">ObjectId</code> when stored in the database.</p> </li>
<li> <p>Mapping conventions can use field access. Notice that the <code class="notranslate">Person</code> class has only getters.</p> </li>
<li> <p>If the constructor argument names match the field names of the stored document, they are used to instantiate the object</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="mongo.examples-repo"><a class="anchor" href="#mongo.examples-repo"></a>10.2. Examples Repository</h3>
<div class="paragraph">
<p>There is a <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples');" target="_blank" rel="noopener noreferrer">GitHub repository with several examples <i class="fa fa-external-link"></i></a> that you can download and play around with to get a feel for how the library works.</p>
</div>
</div>
<div class="sect2">
<h3 id="mongodb-connectors"><a class="anchor" href="#mongodb-connectors"></a>10.3. Connecting to MongoDB with Spring</h3>
<div class="paragraph">
<p>One of the first tasks when using MongoDB and Spring is to create a <code class="notranslate">com.mongodb.MongoClient</code> or <code class="notranslate">com.mongodb.client.MongoClient</code> object using the IoC container. There are two main ways to do this, either by using Java-based bean metadata or by using XML-based bean metadata. Both are discussed in the following sections.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> For those not familiar with how to configure the Spring container using Java-based bean metadata instead of XML-based metadata, see the high-level introduction in the reference docs <a href="javascript:window.open('https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/new-in-3.0.html#new-java-configuration');" target="_blank" rel="noopener noreferrer">here <i class="fa fa-external-link"></i></a> as well as the detailed documentation <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#beans-java-instantiating-container');" target="_blank" rel="noopener noreferrer">here <i class="fa fa-external-link"></i></a>. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="mongo.mongo-java-config"><a class="anchor" href="#mongo.mongo-java-config"></a>10.3.1. Registering a Mongo Instance by using Java-based Metadata</h4>
<div class="paragraph">
<p>The following example shows an example of using Java-based bean metadata to register an instance of a <code class="notranslate">com.mongodb.MongoClient</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 54. Registering a
<code class="notranslate">com.mongodb.MongoClient</code> object using Java-based bean metadata
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
public class AppConfig {

  /*
   * Use the standard Mongo driver API to create a com.mongodb.MongoClient instance.
   */
   public @Bean MongoClient mongoClient() {
       return new MongoClient("localhost");
   }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>This approach lets you use the standard <code class="notranslate">com.mongodb.MongoClient</code> instance, with the container using Spring’s <code class="notranslate">MongoClientFactoryBean</code>. As compared to instantiating a <code class="notranslate">com.mongodb.MongoClient</code> instance directly, the <code class="notranslate">FactoryBean</code> has the added advantage of also providing the container with an <code class="notranslate">ExceptionTranslator</code> implementation that translates MongoDB exceptions to exceptions in Spring’s portable <code class="notranslate">DataAccessException</code> hierarchy for data access classes annotated with the <code class="notranslate">@Repository</code> annotation. This hierarchy and the use of <code class="notranslate">@Repository</code> is described in <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/data-access.html');" target="_blank" rel="noopener noreferrer">Spring’s DAO support features <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>The following example shows an example of a Java-based bean metadata that supports exception translation on <code class="notranslate">@Repository</code> annotated classes:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 55. Registering a
<code class="notranslate">com.mongodb.MongoClient</code> object by using Spring’s MongoClientFactoryBean and enabling Spring’s exception translation support
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
public class AppConfig {

    /*
     * Factory bean that creates the com.mongodb.MongoClient instance
     */
     public @Bean MongoClientFactoryBean mongo() {
          MongoClientFactoryBean mongo = new MongoClientFactoryBean();
          mongo.setHost("localhost");
          return mongo;
     }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To access the <code class="notranslate">com.mongodb.MongoClient</code> object created by the <code class="notranslate">MongoClientFactoryBean</code> in other <code class="notranslate">@Configuration</code> classes or your own classes, use a <code class="notranslate">private @Autowired Mongo mongo;</code> field.</p>
</div>
</div>
<div class="sect3">
<h4 id="mongo.mongo-xml-config"><a class="anchor" href="#mongo.mongo-xml-config"></a>10.3.2. Registering a Mongo Instance by Using XML-based Metadata</h4>
<div class="paragraph">
<p>While you can use Spring’s traditional <code class="notranslate">&lt;beans/&gt;</code> XML namespace to register an instance of <code class="notranslate">com.mongodb.MongoClient</code> with the container, the XML can be quite verbose, as it is general-purpose. XML namespaces are a better alternative to configuring commonly used objects, such as the Mongo instance. The mongo namespace lets you create a Mongo instance server location, replica-sets, and options.</p>
</div>
<div class="paragraph">
<p>To use the Mongo namespace elements, you need to reference the Mongo schema, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 56. XML schema to configure MongoDB
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mongo="http://www.springframework.org/schema/data/mongo"
          xsi:schemaLocation=
          "http://www.springframework.org/schema/context
          https://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/data/mongo https://www.springframework.org/schema/data/mongo/spring-mongo.xsd
          http://www.springframework.org/schema/beans
          https://www.springframework.org/schema/beans/spring-beans.xsd"&gt;

    &lt;!-- Default bean name is 'mongo' --&gt;
    &lt;mongo:mongo-client host="localhost" port="27017"/&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a more advanced configuration with <code class="notranslate">MongoClientOptions</code> (note that these are not recommended values):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 57. XML schema to configure a com.mongodb.MongoClient object with MongoClientOptions
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;beans&gt;

  &lt;mongo:mongo-client host="localhost" port="27017"&gt;
    &lt;mongo:client-options connections-per-host="8"
                   threads-allowed-to-block-for-connection-multiplier="4"
                   connect-timeout="1000"
                   max-wait-time="1500}"
                   auto-connect-retry="true"
                   socket-keep-alive="true"
                   socket-timeout="1500"
                   slave-ok="true"
                   write-number="1"
                   write-timeout="0"
                   write-fsync="true"/&gt;
  &lt;/mongo:mongo-client&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a configuration using replica sets:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 58. XML schema to configure a
<code class="notranslate">com.mongodb.MongoClient</code> object with Replica Sets
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;mongo:mongo-client id="replicaSetMongo" replica-set="127.0.0.1:27017,localhost:27018"/&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="mongo.mongo-db-factory"><a class="anchor" href="#mongo.mongo-db-factory"></a>10.3.3. The MongoDbFactory Interface</h4>
<div class="paragraph">
<p>While <code class="notranslate">com.mongodb.MongoClient</code> is the entry point to the MongoDB driver API, connecting to a specific MongoDB database instance requires additional information, such as the database name and an optional username and password. With that in</p>
</div>
</div>
</div>
</div>
</div></div>
</div>
</section>
<div class="right-sidebar">
<div class="affix"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6108808167664152" data-ad-slot="3102929424" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
</div>
</div>
<div class="ft">
<a href="#toolbar-title" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a>
<footer class="footer">
<div class="footer__container--normal">
<img alt="扫码关注公众号" title="扫码关注公众号" src="static/picture/qr-code.png" width="170" height="170">
<div class="footer__description--normal">
<p class="paragraph footer__author--normal">Docs4dev<sup class="super">&#xAE;</sup>
</p>
<p class="paragraph footer__quote&#45;&#45;normal">
如果你在使用过程中遇到任何问题，可以在 <a href="javascript:window.open('https://github.com/docs4dev/docs4dev-issues');" target="_blank" rel="noopener noreferrer">这里<i class="fa fa-external-link"></i></a> 提issue。
</p>
<div class="footer__main--normal">
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
<a href="javascript:window.open('https://beian.miit.gov.cn/');">
蜀ICP备14021783号-6
</a>
</p>
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
Copyright &#xA9; Docs4dev all
right reserved, powered by <a href="index2.html" target="_blank">Docs4dev</a></p>
</div>
</div>
</div>
<div class="box__issues">
</div>
</footer>
</div>
</div>
</div>
</div>
</div>
<script>
  var hasToc = true;
  /*  var downloadable = /!*false*!/ false;
    var editable = /!*false*!/ false;
    var code = /!*"spring-data-mongodb"*!/ false;
    var version = /!*"2.2.1.RELEASE"*!/ false;
    var type = /!*"reference"*!/ false;
    var lang = /!*"en"*!/ 'en';
    //edit link
    require(["gitbook", "jQuery"], function (gitbook, $) {
      gitbook.events.bind('start', function (e, config) {
        // Add edit toolbar to left
        var chapterId = /!*16339*!/ 0;
        if (downloadable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-download',
            text: '下载',
            onClick: function () {
              window.open('/download?code=' + code + '&version=' + version + '&type=' + type + '&lang=' + lang);
            }
          });
        }
        if (editable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-edit',
            text: '编辑此页',
            onClick: function () {
              window.open('/docs/edit?chapterId=' + chapterId + '&lang=' + lang);
            }
          });
        }
      });
    });*/
</script>
<script>
    var code = "spring-data-mongodb";
    var lang = "en";
  </script>

<script src="static/js/autocomplete-js.js"></script>
<script src="static/js/app.min.js"></script>
<script src="static/js/search.min.js"></script>
</body>
</html>
